2016年4月30日 星期六

遍歷過濾器 (jQuery 9)

官網連結
目前有以下9種:

以下4個我試的結果和基本過濾器 (jQuery 6)一樣,只是寫在括號後面而已
.eq():等於
.first():取第一筆
.last():取最後一筆
.not():取反

這篇寫以下五個範例:
.filter():選擇器選到了之後,又再過濾
.has():選擇器以下有什麼元素,選中的會包括選擇器
.is():判斷是不是選擇器、DOM元素、jQuery物件
.map():取得一個集合中的全部元素
.slice():取得集合裡的一部分

※HTML

※A 

都是div
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
<div class="d">D</div>
<div class="e">E</div>


※B

A裡面再放span
<div class="a">
    A
    <span>aa</span>
</div>
    
<div class="b">
    B
    <span>bb</span>
</div>
    
<div class="c">
    C
    <span>cc</span>
</div>
    
<div class="d">
    D
    <span>dd</span>
</div>
    
<div class="e">
    E
    <span>ee</span>
</div>


※C

A裡面再放div
<div class="a">
    A
    <div>aa</div>
</div>
    
<div class="b">
    B
    <div>bb</div>
</div>
    
<div class="c">
    C
    <div>cc</div>
</div>
    
<div class="d">
    D
    <div>dd</div>
</div>
    
<div class="e">
    E
    <div>ee</div>
</div>


※D

<div class="a">
    A
    <span class="b">B</span>
</div>
<div class="c">C</div>
<div class="d">
    D
    <p class="e">
        E
        <span class="f">F</span>
    </p>
</div>
<div class="g">G</div>
<div class="h">H</div>

※.filter()

裡面可以放四種:
1.放選擇器裡的字串
2.放選擇器:這個我無法了解,下面會說
3.放元素:這個官網和網路上沒找到相關的範例,這個我也無法了解,我試過HTML元素和DOM了,知道的分享一下吧!
4.放函數

我只會第一種和第四種,其他兩種我無法理解

※放選擇器裡的字串、放選擇器、元素

※結果:
A
$('div').filter('.d')、$('div').filter($('.d')):都選到D
$('div').filter(':even'):ACE
$('div').filter($(':even')):BD,完全無法了解
$('div').filter($('div')):全部


B:要注要filter裡面要針對div去設定,假設下面的span有id,設id是沒有作用的
$('div').filter('.d')、$('div').filter($('.d')):都選到D dd
$('div').filter(':even'):A aa C cc E ee
$('div').filter($(':even')):無,完全無法了解
$('div').filter($('div')):全部
$('div').filter($('span')):無


C
$('div').filter('.d')、$('div').filter($('.d')):都選到D dd
$('div').filter(':even'):全部
$('div').filter($(':even')):aa bb cc dd ee,完全無法了解
$('div').filter($('div')):全部


D
$('div').filter('.d')、$('div').filter($('.d')):DEF
$('div').filter(':even'):AB DEF H,而:odd就是CG了
$('div').filter($(':even')):結果是DEF H,而:odd是ABC G,完全無法了解
$('div').filter($('div')):全部
$('div').filter($('span')):無
$('div').filter($('p')):無


※函數

$(function() {
    $('div').filter(function(i) {
        console.log('text=' + $(this).text());
        return $('p', $(this)).length == 1;
        // return i % 2 == 0;
    }).css('color', 'red');
});
----------
<div class="a">
    A
    <span>aa</span>
</div>
    
<div class="b">
    B
    <p>
        p1
        <span>b1</span>
        <span>b2</span>
    </p>
</div>
    
<div class="c">
    C
    <p>
        p2
        <span>cc</span>
    </p>
</div>

※判斷div下面有1個p元素的,所以B p1 b1 b2 C p2 cc會選中

※註解那行是偶數會選中



※.has()

可以放選擇器裡的字串和DOM元素,官方只寫字串,我也還不知道相關的做法,等知道了再補
以D為例:
$('div').has('p'):DEF
$('div').has('span'):ABDEF

以下的兩個不會包括選擇器本身,以這個範例就是div
$('div p'):EF
$('div span'):BF



※.is()

和.filter()一樣可以放4種
※以.filter()的函數範例為例
$(function($) {
    $('div').filter(function(i) {
        console.log('text=' + $(this).text());
        if($(this).is(':last-child')){
            return true;
        }
    }).css('color', 'red');
});

※結果是C p2 cc



※.map()

可以放兩個參數,index和dom 集合

$(function($) {
    var xxx = $(':checkbox').map(function() {
        return this.value;
    }).get();
    alert(xxx);
});
----------
<label for="aaa">A</label>
<input type="checkbox" value="a" id="aaa" name="ya">
    
<label for="bbb">B</label>
<input type="checkbox" value="b" id="bbb" name="ya">
    
<label for="ccc">C</label>
<input type="checkbox" value="c" id="ccc" name="ya">
    
<label for="ddd">D</label>
<input type="checkbox" value="d" id="ddd" name="ya">


※結果是a,b,c,d

※當然也可以用jQuery的寫法,return $(this).val();



※.slice()

以D為例:

$('div').slice():等同$('div').slice(0),取全部
$('div').slice(2):第2個到最後,D是第2個,所以是D~H
$('div').slice(1, 3):注意最後一個不會取,所以是CDEF
$('div').slice(-3, -1):要注意不是(-1,-3),-3一樣不會取,所以是DEFG
$('div').slice(-3):和正數不一樣,是取到-3(含)的意思,所以是DEFGH

2016年4月27日 星期三

內容過濾器、能見度過濾器 (jQuery 8)

※內容過濾器

官網連結
目前有以下4種:


:contains():抓包含的字串,大小寫有差,子字串、後面有「-」也抓的到,可以說是屬性選擇器的6種綜合體(屬性選擇器有7種,去掉!=)
:empty:只有抓空而已(tab、空格、換行、<br>、\t、\r\n都不行)
:has():有包含其他的selector,抓的是選擇器的,不是has裡面的
:parent:父元素以下(含)都算


※:contains()

$(function(){
    $( "span:contains('abc')" ).css('color', 'green');
});
----------
<span>Abc def</span>
<span>abc def</span>
<div>abc def</div>
<span>abC def</span>
<span>abcdef</span>
<span>abc-def</span>

※會抓到2、5、6行

※變色是整行都變色,並不是包含的字變色


※:empty

$(function(){
    $( "td:empty" ).css('background-color', 'lightblue');
});
----------
<table border='1' width="20%">
    <tr>
        <td></td>
        <td> </td>
        <td>
        </td>
        <td><br/></td>
    </tr>
</table>

※只會抓到第一個


※:has()

$(function(){
    $( "div:has(p)" ).css('color', 'red');
    $( "div:has(div)" ).css('color', 'yellow');
    $( "div:has(ul)" ).css('color', 'green');
    $( "div:has(li)" ).css('color', 'blue');
    $( "div:has(span)" ).css('color', 'purple');
});
----------
<div>
    <p>
        A
        <div>B</div>
    </p>
    <ul>
        <li>C</li>
        <li>D</li>
    </ul>
    <span>E</span>
</div>
<div>
    <div>F</div>
<div>

※A~E五個都會抓到,F只有第二個會抓到

※會變顏色的是整個div,也就是選擇器上的div,並不是has裡面的


※:parent

$(function(){
    $( "#a:parent" ).css('color', 'red');
});
----------
<div id="a">
    A
    <div id="b">
        B
        <div id="c">C</div>
    </div>
    <div id="d">
        D
        <div id="e">E</div>
        <div id="f">F</div>
    </div>
    <div id="g">G</div>
</div>
<div id="h">
    H
    <div id="i">I</div>
<div>

※結果:
$( "#a:parent" ):A~G
$( "#b:parent" ):BC
$( "#c:parent" ):D
$( "#d:parent" ):DEF
$( "#e:parent" ):E
$( "#f:parent" ):F
$( "#g:parent" ):G
$( "#h:parent" ):HI
$( "#i:parent" ):I


※能見度過濾器

官網連結
只有兩種:


:hidden:抓隱藏起來的
:visible:抓沒有隱藏的


$(function(){
    alert($( "div:visible" ).text());// A
    alert($( "div:hidden" ).text());// B
    alert($( "input:visible" ).length);// 2
    $('input[disabled]').hide();
    alert($( "input:visible" ).length);// 1
});
----------
<div>A</div>
<div style="display:none;">B</div>
<input type="text" disabled="disabled" />
<input type="text" />

※disabled不算隱藏

2016年4月26日 星期二

子過濾器 (jQuery 7)

官網連結

目前總共有10個:
:first-child:取指定元素的第一筆,不會忽略其他元素,第一筆不是指定的元素,就抓不到
:last-child:取指定元素的最後一筆,不會忽略其他元素,最後一筆不是指定的元素,就抓不到

:first-of-type:取指定元素的第一筆,忽略其他元素,只看的到自己的元素
:last-of-type:取指定元素的最後一筆,忽略其他元素,只看的到自己的元素

:only-child:只有一個才會選中,所以才叫only,不會忽略其他元素,唯一的一筆不是指定的元素,就抓不到
:only-of-type:只有一個才會選中,所以才叫only,忽略其他元素,只看的到自己的元素


※以下4個都是從1開始,和:eq()、:gt()、:lt()從0開始不一樣
裡面可以放3種值(或者說4種)
1.數字,只取一筆
2.odd/even,也就是奇數、偶數(這個就不做範例了,第1個數字的會了,想一下就OK了)
3.公式,用「n」,表示每幾個的意思,大小寫沒差


:nth-child():取指定元素的第x筆或(每x筆),從前面開始找,不會忽略其他元素,第x筆或(每x筆)不是指定的元素,就抓不到
:nth-last-child():取指定元素的第x筆或(每x筆),從後面開始找,不會忽略其他元素,第x筆或(每x筆)不是指定的元素,就抓不到

:nth-of-type():取指定元素的第x筆或(每x筆),從前面開始找,忽略其他元素,只看的到自己的元素
:nth-last-of-type():取指定元素的第x筆或(每x筆),從後面開始找,忽略其他元素,只看的到自己的元素


※有child所有元素都看的到,有of-type只會看到指定的元素



※以下列出A~D四個HTML,測試8個子過濾器,剩下2個only,還有另外的範例

※A

<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
<span>E</span>


※B

<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
<em>E</em>


※C

<div>
    <span>A</span>
    <span>B</span>
    <span>C</span>
    <span>D</span>
    <span>E</span>
    <span>F</span>
    <span>G</span>
</div>
<div>
    <span>H</span>
    <span>I</span>
    <span>J</span>
    <span>K</span>
    <span>L</span>
</div>
<div>
    <span>M</span>
    <span>N</span>
    <span>O</span>
    <span>P</span>
    <span>Q</span>
    <span>R</span>
    <span>S</span>
</div>


※D

<div>
    <span>A</span>
    <span>B</span>
    <em>C</em>
    <span>D</span>
    <span>E</span>
    <span>F</span>
    <span>G</span>
</div>
<div>
    <span>H</span>
    <b>I</b>
    <span>J</span>
    <span>K</span>
    <span>L</span>
</div>
<div>
    <i>M</i>
    <span>N</span>
    <span>O</span>
    <span>P</span>
    <span>Q</span>
    <span>R</span>
    <span>S</span>
</div>



※:first-child/:last-child

A:
$('span:first-child'):A
$('span:last-child'):E

B:
$('span:first-child'):A
$('span:last-child'):無

C:
$('span:first-child'):AHM
$('span:last-child'):GLS

D:
$('span:first-child'):AH
$('span:last-child'):GLS



※:first-of-type/:last-of-type

A:
$('span:first-of-type'):A
$('span:last-of-type'):E

B:
$('span:first-of-type'):A
$('span:last-of-type'):D

C:
$('span:first-of-type'):AHM
$('span:last-of-type'):GLS

D:
$('span:first-of-type'):AHN
$('span:last-of-type'):GLS



※:nth-child()/:nth-last-child()

 A:
$('span:nth-child(5)'):E
$('span:nth-last-child(5)'):A

$('span:nth-child(2n)'):BD
$('span:nth-last-child(2n)'):BD

$('span:nth-child(2n-1)'):ACE
$('span:nth-last-child(2n-1)'):ACE


B:
$('span:nth-child(5)'):無,如果下面還有一行<span>F</span>,還是不會選到
$('span:nth-last-child(5)'):A,但如果下面還有一行<span>F</span>,會選到B

$('span:nth-child(2n)'):BD
$('span:nth-last-child(2n)'):BD

$('span:nth-child(2n-1)'):AC
$('span:nth-last-child(2n-1)'):AC


C:
$('span:nth-child(2)'):BIN
$('span:nth-last-child(2)'):FKR

$('span:nth-child(2n)'):BDF IK NPR
$('span:nth-last-child(2n)'):BDF IK NPR

$('span:nth-child(2n-1)'):ACEG HJL MOQS
$('span:nth-last-child(2n-1)'):ACEG HJL MOQS


D:
$('span:nth-child(2)'):BN
$('span:nth-last-child(2)'):FKR

$('span:nth-child(2n)'):BDF K NPR
$('span:nth-last-child(2n)'):BDF K NPR

$('span:nth-child(2n-1)'):AEG HJL OQS
$('span:nth-last-child(2n-1)'):AEG HJL OQS



※:nth-of-type()/:nth-last-of-type()

A:
$('span:nth-of-type(5)'):E
$('span:nth-last-of-type(5)'):A

$('span:nth-of-type(2n)'):BD
$('span:nth-last-of-type(2n)'):BD

$('span:nth-of-type(2n-1)'):ACE
$('span:nth-last-of-type(2n-1)'):ACE


B:
$('span:nth-of-type(5)'):無,但如果下面還有一行<span>F</span>,會選到F
$('span:nth-last-of-type(5)'):無,但如果下面還有一行<span>F</span>,會選到A

$('span:nth-of-type(2n)'):BD
$('span:nth-last-of-type(2n)'):AC

$('span:nth-of-type(2n-1)'):AC
$('span:nth-last-of-type(2n-1)'):BD


C:
$('span:nth-of-type(2)'):BIN
$('span:nth-last-of-type(2)'):FKR

$('span:nth-of-type(2n)'):BDF IK NPR
$('span:nth-last-of-type(2n)'):BDF IK NPR

$('span:nth-of-type(2n-1)'):ACEG HJL MOQS
$('span:nth-last-of-type(2n-1)'):ACEG HJL MOQS


D:
$('span:nth-of-type(2)'):BJO
$('span:nth-last-of-type(2)'):FKR

$('span:nth-of-type(2n)'):BEG JL OQS
$('span:nth-last-of-type(2n)'):ADF HK NPR

$('span:nth-of-type(2n-1)'):ADF HK NPR
$('span:nth-last-of-type(2n-1)'):BEG JL OQS



※:only-child/:only-of-type

※範例1

<span>A</span>

※結果:
$('span:only-child'):A,就算是多一行<br />或者兩個span,中間空一格,也抓不到
但如果用<div>、<p>…等包起來就可以

$('span:only-of-type'):A,多一行<br />也可以,它只認span,所以兩個span才不行,
當然用<div>、<p>…等包起來還是可以

※範例2

<em>A</em>
<span>B</span>
<b>C</b>

※結果:
$('span:only-child'):無
$('span:only-of-type'):B


※範例3

<div>
    <span>A</span>
    <span>B</span>
</div>
<div>
    <span>C</span>
</div>
<div>
    <span>D</span>
    <span>E</span>
    <span>F</span>
</div>
<div>
    <span>G</span>
</div>

※結果:
$('span:only-child'):CG
$('span:only-of-type'):CG


※範例4

<div>
    <span>A</span>
    <span>B</span>
</div>
<div>
    <span>C</span>
</div>
<div>
    <em>D</em>
    <span>E</span>
    <b>F</b>
</div>
<div>
    <span>G</span>
</div>

※結果:
$('span:only-child'):CG
$('span:only-of-type'):CEG

2016年4月24日 星期日

基本過濾器 (jQuery 6)

官網連結

目前總共有14個:

以下3個1.8(含)之後可接受負數,1.7(含)以上的我才會寫,想知道的看官網藍色的那一條最右邊都有寫
:eq():equals,等於,從0開始,和.eq()相同,但.eq()很早就可以用負數了,兩個現在只差在寫在括號裡面或外面而已; 不過.eq()是放在遍歷裡,所以跑迴圈時,儘量用.eq,其他再用:eq
:gt():greater than, 大於,從0開始,目前沒有.gt()這種東西
:lt():last than小於,從0開始,目前沒有.lt()這種東西

:first:取第一筆
:last:取最後一筆

:odd:取奇數
:even:取偶數

:header:取HTML的H1~H6
:not():取反

:lang():抓屬性lang的字串,大小寫沒差
:root:取得HTML物件
:animated:取得有動畫的物件
:target:取得網址上#後面的字
:focus:jQuery 5介紹過,所以它是選擇器,也是過濾器


※:eq、:gt、:lt、:first、:last

$(function() {
    $("ul:eq(1) > li:eq(1)").css('background-color', 'red');
    
    for(var i=0; i<$('ul').length; i++){
        $("ul:eq(" + i + ") > li:lt(1)").css('background-color', 'red');
    }
    
    $("ul:last > li:first").css('background-color', 'red');
});
----------
<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>
<ul>
    <li>F</li>
    <li>G</li>
</ul>
<ul>
    <li>H</li>
    <li>I</li>
    <li>J</li>
</ul>

※$("ul:eq(1) > li:eq(1)"),是比較好的寫法,G被選中

※$("ul > li:eq(1)"),只有B會被選中,並不是所有的ul,我試的結果也只有:eq指的是第一個,其他都是指全部的ul

※如果每一個ul都要選中,我想到的是用迴圈

※$("ul > li:lt(1)"),小於1(B)的,所以結果是A

※$("ul > li:gt(1)"),大於1(B)的,所以C~J都會被選中

※$("ul > li:first"),只有A會被選中

※$("ul > li:last"),只有J會被選中


※:odd、:even


$("ul li:odd").css('background-color', 'lightgreen');
$("ul li:even").css('background-color', 'pink');

※ul一樣指全部,也是從0開始,0是偶數,所以第一行是粉紅色


※:header、:not

$(function() {
    $(':header').css('color', 'red');
    $('input:not(:disabled)').css('color', 'green');
    $(':header').css('color', 'red');
});
----------
<h1>1</h1>
<h2>2</h2>
<h3>3</h3>
<h4>4</h4>
<h5>5</h5>
<h6>6</h6>
<h7>7</h7>
<h8>8</h8>
<h9>9</h9>
<h10>10</h10>
    
<input value="a" />
<input value="b" />
<input value="c" disabled="disabled"/>
<input value="d" />
<input value="e" disabled="disabled"/>

※雖然HTML沒有H7~H9,但我試也是可以(但不會換行),H10(含)以上就不行了


※:lang

$(function() {
    $("span:lang(en_us)").css('background-color', 'red');
    $("span:lang(zh_tw)").css('color', 'green');
});
----------
<span lang="EN_US">
    a
    <span>
        b
        <span>c</span>
    </span>
</span>
<span lang="zh_tw">
    1
    <span>
        2
        <span>3</span>
    </span>
</span>

※很多屬性都有lang,裡面的字串對應到:lang的()裡就能選中了,所以不一定要用zh_tw這種格式,大小寫沒差


※:root

$(function() {
    var xxx = $(':root');
    // debugger;
    alert(xxx[0].nodeName);
});

※取得HTML物件,但為什麼可以.nodeName呢?還可以點哪些呢?
打開註解那一行後,瀏覽器按F12,然後再按重整,如下操作(只截IE8、IE11和Chrome的圖):



※最後的圖是IE8,要先Start Debugging再重整才有作用

※有下拉是因為滑鼠要放在變數(xxx)不動,出來後,左邊就是可以點的名稱了,右邊是值


※:animate

$(function() {
    $("div").animate({width: "500px"}, "slow");
    $("span").animate({width: "500px"}, "slow");
    var xxx = $(":animated");
    alert(xxx[0].nodeName);
    alert(xxx[1].nodeName);
});
----------
<div></div>
<span></span>

※必須先有動畫,所以前兩行讓下面的div和span有動畫,然後就可以取得物件,能點什麼名稱,和上面的圖一樣的做法


※:target

$(function($) {
    $('button').click(function(){
        test();
    });
});
    
function test(){
    $(':target').css('color', 'red');
}
----------
<button>test</button>
<div id="xxx">div</div>
<a href="#xxx">xxx</a>

※a href="#"其實就是書籤的功能,點擊超連結後,網址後面就會多個#xxx,這時再按button就會看到變化了

表單選擇器 (jQuery 5)

官網連結

※input

目前有15個,先說明下面這10個
:input:HTML元素是input、textarea、select、button
以下9個都是input裡的屬性:

:text:input type是text的
:password:input type是password的
:checkbox:input type是checkbox的
:radio:input type是radio的
:file:input type是file的
:button:input type是button、HTML元素是button的
:image:input type是image,HTML元素是img的不會選中
:reset:input type是reset的
:submit:input type是submit、HTML元素是button的(type是button不會選中),IE瀏覽器有些版本的button不會選中,官網有寫


※測試

<style>
    .xxx{ background-color: lightgreen; }
</style>
    
    
function input(){
    $(':input').addClass('xxx');
    // $(':input').attr('checked', 'checked');
}
    
function text(){
    $(':text').addClass('xxx');
}
    
function password(){
    $(':password').addClass('xxx');
}
    
function file(){
    $(':file').addClass('xxx');
}
    
function reset(){
    $(':reset').addClass('xxx');
}
    
function submit(){
    $(':submit').addClass('xxx');
}
    
function image(){
    $(':image').addClass('xxx');
}
    
function button(){
    $(':button').addClass('xxx');
}
    
function checkbox(){
    $(':checkbox').attr('checked', 'checked');
}
    
function radio(){
    $(':radio').addClass('xxx');
}
    
function hid(){
    alert($(':input').length);
}
----------
<form>
    <input type="text" value="t" />text<br />
    <input type="password" value="p" />password<br />
    <input type="file" />file<br />
    <textarea>textarea</textarea>textarea<br />
    <input type="hidden" value="h" />hidden<br />
    <input type="reset" value="重置" />reset<br />
    <input type="submit" value="送交" />submit<br />
    
    <input type="image" />image1<br />
    <img alt="" src="">image2<br />
    
    <input type="button" value="b1" />button1<br />
    <button value="b2">Button2</button>button2<br />
    
    <input type="checkbox" name="alphabeta" value="A" />a
    <input type="checkbox" name="alphabeta" value="B" />b
    <input type="checkbox" name="alphabeta" value="C" />c<br />
    
    <input type="radio" name="digit" value="1" />one
    <input type="radio" name="digit" value="2" />two
    <input type="radio" name="digit" value="3" />three<br />
    
    <select>
        <option value="o1">Option1</option>
        <option value="o2">Option2</option>
        <option value="o3">Option3</option>
    </select><br />
</form>
<br />
<br />
<button onclick="input()">測input</button>
<button onclick="text()">測text</button>
<button onclick="password()">測password</button>
    
<button onclick="file()">測file</button>
<button onclick="reset()">測reset</button>
<button onclick="submit()">測submit</button>
    
<button onclick="image()">測image</button>
<button onclick="button()">測button</button>
<button onclick="checkbox()">測checkbox</button>
<button onclick="radio()">測radio</button>
<button onclick="hid()">測hidden</button>

※由於:input對checkbox看不出效果,所以我在input函數有註解一行,打開後,連radio也會勾選,很正常,只是要測:input對checkbox是有效的而已
有些jQuery的版本要將attr替換成prop

※使用:input時hidden也抓的到,按下測:input按鈕時,只有一個img沒抓到,算一算有27個,而按下測hidden的按鈕時,有28個
或者多刪一些不必要的來測就知道了

※我本來hid()是寫hidden(),發現沒有作用,它也不是關鍵字或保留字,但就是沒用



※狀態

:checked:判斷checkbox、radio用的勾選
:selected:判斷select option用的勾選
:disabled:判斷是disabled
:enabled:判斷不是disabled
:focus:判斷是否聚焦(游標進去的狀態)


※:enabled/:disabled

$(function() {
    $(":enabled").css('color', 'green');
    $(":disabled").css('color', 'red');
});
----------
<input type="text" value="a" />text<br />
<input type="text" value="b" disabled="disabled" />disabled<br />
<input type="text" value="c" readonly="readonly" />readonly<br />

※結果b是紅色,其他都是綠色


※:checked

$(function() {
    $("[name='digit']:checked").css('background-color', 'red');
    alert($("[name='alphabeta']:checked").length);
});
----------
<input type="checkbox" name="alphabeta" value="A" checked="checked" />a
<input type="checkbox" name="alphabeta" value="B" checked />b
<input type="checkbox" name="alphabeta" value="C" checked=true />c
<input type="checkbox" name="alphabeta" value="D" checked="true" />d
<input type="checkbox" name="alphabeta" value="E" />e<br />
    
<input type="radio" name="digit" value="1" />one
<input type="radio" name="digit" value="2" checked="checked" />two
<input type="radio" name="digit" value="3" />three<br />

※checked有四種寫法,最好的就是checked='checked',其他的有可能瀏覽器不支援


※:selected單選

$(function() {
    alert($("option:selected").length);
});
----------
<select>
    <option>Option1</option>
    <option selected="selected">Option2</option>
    <option>Option3</option>
</select>


※:selected多選

function test(){
    $('option:selected').each(function(){
        alert($(this).val());
    });
}
----------
<select multiple="multiple">
    <option value="o1">Option1</option>
    <option value="o2" selected="selected">Option2</option>
    <option value="o3">Option3</option>
    <option value="o4">Option4</option>
    <option value="o5">Option5</option>
</select>
<button onclick="test()">測試</button>

※要按右Ctrl鍵不放,再按滑鼠左鍵


※:focus

$(function() {
    $('*').focus(function(){
        test();
    });
});
    
function test(){
    if($(':checkbox').is(':focus')){
        alert('a');
    } else if($(':radio').is(':focus')){
        alert('b');
    } else if($(':text').is(':focus')){
        alert('c');
    } else if($('#tt').is(':focus')){
        alert('d');
    }
}
----------
<input type="checkbox" />
<input type="checkbox" />
<input type="radio" />
<input type="radio" />
<input type="text" value="text" />
<textarea id="tt">textarea</textarea>

※option用這一招沒用,因為滑鼠游標進不去,或者用disabled也是點不進去,但readonly是可以的

※官網那一招進的去,還蠻厲害的,可自行參考

2016年4月23日 星期六

階層選擇器 (jQuery 4)

官網連結

※>和空格

$(function() {
    $("div > p" ).css('color', 'lightgreen');
});
----------
<div>
    div1
    <p>p1</p>
    <div>
        div2
        <p>p2</p>
    </div>
</div>
<div>
    div3
    <form>
        <p>p3</p>
    </form>
</div>

※「>」是有父子關係的,以這個例子就是div的兒子是p的,所以p1和p2會被選中

※如果下$("div p" ),就沒有父子關係了,所以不管幾層,div下有p的就被選中,所以p1、p2、p3都會被選中

※如果下$("div >"),表示div的兒子都要選中,所以p1、div2、p2、p3都會選中

※如果下$("div > div > p"),那就只有p2被選中



※+

$(function() {
    $("a + div + p" ).css('color', 'lightgreen');
});
----------
<span>span1</span>
<a>a</a>
<div>
    div
    <span>span2</span>
</div>
<p>p

※+表示同一層的下一個,英文是next,所以上一個不是喔!

※這個例子,p會被選中

※如果下$("a + div+"),p也會被選中,因為表示div的下一個,沒有特別指定是什麼元素
假設程式碼的最後是div不是p,那範例就沒有東西被選中,而這個例子div還是會被選中

※如果下$("a + div"),div和span2會被選中

※$("a + div"),a和div之間不能有其他標籤


※~

$(function() {
    $("a ~ div" ).css('color', 'lightgreen');
});
----------
<div>div1</div>
<a>a</a>
<div>div2</div>
<div>
    div3
    <span>span</span>
</div>
<input type="text" value="input" />

※~表示同一層的意思,但上一個(prev)還是不會理它,以這個例子就是和a同層,而且是div的要選中,所以會選中div2、div3、span

※如果下$("a ~" ),那div2、div3、span、input會被選中

※如果a和div中間有其他元素也是可以的


※不管那一種階層,自己都不會選中

屬性選擇器 (jQuery 3)

官網連結

※七種屬性

有分大小寫

$(function($) {
    $("[name|='link']").css("color", "lightblue");
});
----------
<a name="link">a</a>
<a name="link ">b</a>
<a name=" link">c</a>
<a name="Dlink">d</a>
<a name="link-a">e</a>
<a name="linking">f</a>
<a name="D-link">g</a>

※以上面的例子,效果成功的如下:
=:剛好是什麼的,以下的6種都是以這個為出發點,成功的是a
!=:不是什麼的,成功的是全部,以下會說明
*=:字串裡的其中一部分或全部,都抓的到,成功的是全部
^=:開頭是什麼的,成功的是abef
$=:結尾是什麼的,成功的是acdg
~=:前後有空格也抓的到,成功的是abc
|=:後面有接「-」也抓的到,成功的是ae

※!=

注意官網的最後一句:or do have the specified attribute but not with a certain value.
沒有value屬性會選中的意思,所以<div><span><p>沒有value屬性都會選中

以下的input是有value屬性的:所以就只是不等於的意思,我試過不給value和value=""都是很正常的

<input name="link" value="a"/>
<input name="link " value="b"/>
<input name=" link" value="c"/>
<input name="Dlink" value="d"/>
<input name="link-a" value="e"/>
<input name="linking" value="f"/>
<input name="D-link" value="g"/>

※將超連結的a,改成input後,「!=」終於是b~g了

※官方有說這不是CSS的規範,所以效能差,使用$( "your-pure-css-selector" ).not( "[name='value']" )會比較好

※所以「!=」最好用在有value屬性時


※一次選多個


$("[id][name$='link']" ).css('border', '1px solid red');
----------
<input id="" name="link" value="a"/>
<input name="link " value="b"/>
<input name=" link" value="c"/>
<input name="Dlink" value="d"/>

※只有a會被選中,[id]表示要設定id,像我的a是空的也可以,如果要更準確,可以下[id="xxx"]

2016年4月22日 星期五

程式進入點、衝突 (jQuery 1)

如果還沒安裝好jQuery,可參考這篇設定,為了省版面,以下就不把<script>寫出來了,HTML用「---」隔開

官網連結:load(load有兩種,描述有javascript的)、ready

jQuery1和2可以說是一樣的,最大的差別是jQuery2不支援6~8,官網有說

我還有找到中文版的jQuery,和官網簡直一模一樣,請參考這裡
這個網址的教學也有整套的,可以參考看看

※程式進入點

官網連結
可以看出,在1.8時,已將load和unload標記為過時了,但過時不代表移除,還是能用

$(window).load(function() {
    alert('two');
    $('img').css('border', '20px solid red');
});
    
window.onload = function(){
    alert('three');
    $('img').css('border', '20px solid yellow');
}
    
window.onload = function(){
    alert('four');
    $('img').css('border', '20px solid green');
}
    
$(function() {
    alert('zero');
    $('img').css('border', '20px solid blue');
});
    
$(document).ready(function() {
    alert('one');
    $('img').css('border', '20px solid lightblue');
});
--------------------
<img src="Koala.bmp">

※load和javascript的window.onload類似,
但window.onload寫很多個都只會執行最後一個,
load寫多都可以執行到,而先後順序,load比onload還快

※ready官網說有三種方法,但其中一種不建議使用,所以我只寫上面程式碼的zero和one
它是最先執行的(前面兩個必需等到圖片都載入才會執行),而且可以寫很多個,都不會有覆蓋的情形

※官網也說「$」可用「jQuery」代替,大小寫有差

※以上我用Chrome測比較明顯,圖片還沒出來時,會先執行zero-->one,img它已經抓到了(但屬性src還沒,所以圖片還沒顯示),旁邊的框從藍色變淺藍色
然後執行two-->four,旁邊的框從紅色變綠色

※使用IE11測試,一開始就有圖片了,然後它會全部alert完,直接將框框變成最後的顏色,中間的顏色都沒出現過

※總結就是jQuery的兩種方法都可以寫很多個,一樣的方法,先寫的先執行
ready不會等到圖片載入就開始執行了,所以是最先執行的
再來是load方法,最後是onload



※衝突

有可能使用其他的library,也會用到「$」,如「propotype.js」,只要有import的那一頁,就不能再用「$」了,因為propotype有用到,這就是在專案為什麼有時候可以用,有時候不能用的原因,使用以下的語法,可以自定符號,取代「$」

jQuery預設的「$」和「jQuery」是等價的,所以懶的設定可以直接用「jQuery」取代「$」
官網連結

※noConflict沒參數的設定

// A
jQuery.noConflict();
$( document ).ready(function() {
    alert('init');
});
    
// B
var Q = jQuery.noConflict();
Q( document ).ready(function() {
    alert('init');
});

※使用A的方式,一經設定(所以寫在ready後面還是可以),就只能寫「jQuery」開頭才有用,如上的寫法是抓不到jQuery的,而且不管有沒有加參數都是一樣的結果

※使用B的方式,取一個變數名(不一定一個字元),就可以拿它來代替「$」了


※noConflict有參數的設定

參數是boolean,表示要不要從全域範圍移除jQuery
我試的結果只對jQuery開頭的有作用


// C
jQuery.noConflict(true);
jQuery( document ).ready(function() {
    alert('init');
});
    
// D
var Q = jQuery.noConflict(true);
Q( document ).ready(function() {
    alert('init');
});

※使用C的方式,不管用「$」還是「jQuery」開頭,jQuery都沒有作用了
如果給false,jQuery開頭的可以執行

※使用D的方式(和B一樣),取一個變數名(不一定一個字元),就可以拿它來代替「$」了



※unload

$(window).unload(function() { 
    alert("離開了"); 
});

※我在IE 11試的結果,重整、在網址列打別的網址後按enter、按下一頁都會觸發;
但Chrome沒有作用

2016年4月21日 星期四

注意事項 (JavaScript 1)

※任意地點的script

<!DOCTYPE html>
<script>alert('a');</script>
    
<html>
    <script>alert('b');</script>
    
    <head>
        <script>alert('c');</script>
    </head>
    
    <script>alert('d');</script>
    
    <body>
        <script>alert('e');</script>
    </body>
    
    <script>alert('f');</script>
</html>
    
<script>alert('g');</script>

※以上七個地方都可以,但真正只能放在 head 和 body 裡而已,因為瀏覽器會將 abcd 放在 head 裡;efg 放在 body 裡



※同script區塊

<script>
    alert(a);
    var a = 'a';
</script>

※大部分的程式語言都一定要宣告,不能就會編譯錯誤,但js有預編譯的功能,能將變數和function先編譯好,但只有等號的左邊會先編譯好,所以會印出undefined(不管有沒有給值都一樣)

※只有 var 可以,const、let都會編譯錯誤,就算加上 use strict 結果也不會改變
雖然不宣告 var 也是 全域的意思,但在這裡不加 var 也是會錯,所以總規一句就是只宣告 var 關鍵字才會

※不同script區塊

<script>
    alert(a);
</script>
    
<script>
    var a = 'a';
</script>

※js是以一個script區塊執行完才會執行下一個script區塊,所以雖然只是將最後一行多個script包起來,這時候就會有大部分的程式語言的錯誤訊息,找不到物件


※預編譯 function

a();
function a(){
    alert('a');
}
    
b();
var b = new Function('alert("b");');
     
c();
var c = function(){
    alert('c');
}
     
d();
var d = () => {
    alert('d');
}

※預編譯 function,分成有沒有「()」
1.無圓括號
如果印a可以印出整個 function 的內容
而 b c d 是 undefined

2.有圓括號
a()會印出a;而b~d會出現語法錯誤:xxx is not a function

3.以上兩點 加上 use strict 不會改變其結果

※d是 lambda 的寫法,用 IE11 還是不支援

※注意名稱會被覆蓋的問題,如下:

function x() {
    return 22;
}
var x = 10;
console.log(x); // 10

※這裡的 function 的寫法,會被有宣告 var x 開頭的覆蓋,方法屬性都一樣

※總結:
function a(){}這種的會先提前,再來是有宣告 var 關鍵字的提前,但是不包括 = 之後的部分,其中名稱一樣的會後者蓋前者,這裡講的是全域作用域,函數作用域裡也是一樣的

練習

var x1 = 'xxx';
function fun1(){
    console.log(x1); // xxx
}
fun1();
console.log("===============");
    
    
    
var x2 = 'xxx';
function fun2(){
    console.log(x2); // undefined
    var x2 = 'ooo'; // 此為函數裡的x
}
fun2();
console.log(x2); // xxx
console.log("===============");
    
    
    
var x3 = 'xxx';
function fun3(){
    console.log(x3); // xxx
    x3 = 'ooo';
}
fun3();
console.log(x3); // ooo
console.log("===============");
    
    
    
var x4 = 'xxx';
function fun4(x4){ // 參數裡的變數為函數的var
    console.log(x4); // undefined
    x4 = 'ooo';
}
fun4();
console.log(x4); // xxx
console.log("===============");
    
    
    
var x5 = 'xxx';
function fun5(x5){
    console.log(x5); // zzz
    x5 = 'ooo';
}
fun5('zzz');
console.log(x5); // xxx



※多個window.onload

window.onload是全部的頁面載入完才執行的
載入是從上到下,所以如果沒有用這個將程式碼包起來,有可能會找不到物件,因為它還沒生成,如果是寫在最下面那就沒有關係

<script>
    window.onload = function(){alert('a');}
    window.onload = function(){alert('b');}
</script>
    
<script>
    window.onload = function(){alert('c');}
</script>

※雖然可以寫多個,但只會直行最後一個,後者蓋前者,所以會印出c


※同名

window.onload = function(){
    aaa();
};
    
// A
var aaa = function(){
    alert('a1');
}
    
// B
function aaa(){
    alert('a2');
}

※如果一個是屬性、一個是方法,不管順序,會以屬性為主

※如果有多個同名的A或B的寫法,那會後者蓋前者

※如果像上面A和B都有,會以宣告變數的A為主(A包括其他三種以var開頭的寫法)

※就算其中一個有參數、一個沒參數,結果還是一樣,javascript 不管參數的

※以上只發生在用「var」關鍵字宣告時



※同名2


<script type="text/javascript">
    function test(){
        alert('main test');
    }
</script>
<script type="text/javascript" src="extTest.js"></script>

※載入另外一個檔案也是會覆蓋,如最後一行如果有test function,會以另外一個檔案為主,但如果將它寫在第一個script的上面,那又變成main test為主


※不支援javascript一

window.onload = function(){
    <!--
        aaa();
    //-->
};

※「//」是javascript單行註解;「/*    */」是javascript多行註解
「<!--    -->」是HTML的多行註解
如果不支援javascript,那就會報錯,針對不支援的可以用HTML的註解包起來

※但如果javascript和HTML都有支援,那用HTML註解包起來也不會執行,所以用上面的寫法,分開多行,將最後的「-->」用javascript註解(兩種都可以)包起來可以執行的到
而不支援的看不種「//」,所以就會很順利的註解了


※不支援javascript二

<script>
// ...
</script>
<noscript>
    <h1> not support!</h1>
</noscript>

※和<script>同層,裡面寫HTML就可以了


※設定瀏覽器禁用javascript

這裡只介紹IE和Chrome

IE:

工具-->網際網路選項-->安全性,然後看圖操作




我沒重新啟動時,畫面如上,按「允許被封鎖的內容」還是可以;重啟後,就沒有提示了


Chrome:


如果下圖沒看到,要按「顯示進階設定」


2016年4月19日 星期二

基本選擇器 (jQuery 2)

※基本選擇器

有元素選擇器(抓HTML)、類別選擇器(.)、ID選擇器(#)、名稱選擇器(name)、星選擇器(*)
官網連結,在官網API文件的左邊有個叫Selectors,裡面有Basic


$(function() {
    $('p').css('font-style', 'italic');
    $('[name="zzz"]').css('background-color', 'yellow');
    $('#xxx').css('font-size', '24px');
    $('.ooo').css('color', 'red');
    
    $('#x\\.o').css('font-family', 'impact');
    $('#x\\:o').css('font-weight', 'bold');
    $('#\\[xox\\]').css('background-color', 'green');
});
    
<body>
    <p>p</p>
    
    <input type="text" name="zzz" value="z1" />
    <div name="zzz">z2</div>
    <p name="zzz">z3</p>
    
    <div id="xxx">x1</div>
    <div id="xxx">x2</div>
    <div id="xxx">x3</div>
    
    <h3 class="ooo">o</h3>
    
    <div id="x.o">s1</div>
    <div id="x:o">s2</div>
    <div id="[xox]">s3</div>
</body>

※結果:

※單引號和雙引號沒差,主要是用在第二個的情形,因為兩組打一樣會找不到,一找不到連下面的程式都不會執行,所以後面的都沒有效果

※name因為可以很多,所以要用陣列包起來([])

※id只能一個,如果寫很多,只會抓到第1個

※class可以設成多個,要用空格隔開,如<h3 class="ooo xxx">o</h3>,這時如果用$('.ooo xxx')是抓不到的,要用$('.ooo')或$('.xxx')
只有class是這樣,name和id都不會這樣

※有特殊字元,如上面的「.:[]」,前面要用跳脫字元(\\)才抓的到
官網的id選擇器有個叫escape those characters with backslashes的超連結,有教不用跳脫字元的用法

※id和class不能用$('id=""')、$('class=""'),會抓不到

※css方法是學css用的,寫的是「key:value」,可以參考W3C這裡

※要設定多組css有三種方法,如下
// 1
$('.ooo').css('color', 'red');
$('.ooo').css('font-size', '70px');
    
// 2
$('.ooo').css('color', 'red').css('font-size', '70px');
    
// 3
$('.ooo').css({'color':'red', 'font-size':'70px'});

※注意用「{}」時,裡面變「:」


※一次選多個

如果要好幾個的效果要一樣,要用「,」隔開,如下:
$('.ooo, p, #xxx').css('color', 'red');

※class是ooo,還有元素p,和id是xxx的效果都會一樣


※星選擇器

$('div *').css('background-color', 'lightblue');
----------
<p>p</p>
<div>
    <div>div</div>
    <p>p</p>
</div>

※這樣子會將div以下(不包括自己)設定背景色

※也可以用$('body *')針對整張網頁

※結果為下圖,黑線上面是div *,黑線下面是body *

※如果是用$('*'),那麼就是針對整張網頁,以上面的例子,就等於在設定背景色

2016年4月17日 星期日

Eclipse 配置 jQuery 和 安裝jQuery的Content assist

※Eclipse 配置 jQuery

Eclipse安裝好開啟後(想開啟,java也要安裝),去官網下載jQuery,複製到隨便一個地方

※正確的設定

<script type="text/javascript" src="jquery-2.2.3.js"></script>
<script type="text/javascript">
    $(function() {
        alert('hello jQuery!');
    });
</script>


以下圖為例

※綠框的程式碼就在右邊,紅框因為和index.html是同層,所以src直接寫就可以了

※常見錯誤1

可以用滑鼠直接將紅框拖曳到src裡面,但路徑是WebContent開頭,所以不正確,而且按Ctrl鍵不放,然後按滑鼠左鍵也沒反應


※常見錯誤2

如果是用「/」開頭,如「/jquery-2.2.3.js」,Ctrl和左鍵是有連到的,但還是不正確


※常見錯誤3

<script type="text/javascript" src="jquery-2.2.3.js" />
<script type="text/javascript">
    $(function() {
        alert('hello jQuery!');
    });
</script>

※只是將「<script></script>」,改成「<script />」就不對了


※常見錯誤4

<script type="text/javascript" src="jquery-2.2.3.js">
    $(function() {
        alert('hello jQuery!');
    });
</script>

※直接將兩個script合在一起也是不正確的

如果不想下載jQuery又想執行jQuery,就將src指向jQuery的網址吧!我指的是官網範例程式的網址,如:src="https://code.jquery.com/jquery-1.10.2.js",當然要連網路才行


※安裝jQuery的Content assist

※有時候不會提示,但實際上是有方法的,只能說不要太依賴Content assist,一切都已官網為主,我只把它當作少打錯字的工具而已


Help-->Eclipse Marketplace出現如下的畫面


安裝好會提示重啟Eclipse,重啟後,在自己的專案按右鍵-->Properties後,如下操作



選擇適合的版本後,按下Finish完成(如果版本不對,還是可以用,只是新的方法不會提示)
現在輸入「$().」,一打「.」有些Eclipse的版本就可以了,如果沒有還要再設定

在Eclipse的上面找到Window-->Preferences後,如下操作:

※Enable auto activeation一勾,下面的三個子項才可以設定,上面都是預設的
.Auto activation delay:延遲300毫秒(0.3秒),也就是緩衝

.Auto activation triggers for JavaScript:框裡輸入什麼,只要一打就會提示,預設是「.」,也可以將a~z打進去,這樣子打英文和.都會提示,但較浪費記憶體

.Auto activation triggers for JSDoc:在註解裡輸入框裡的字元後會有註解的相關提示
以Java來說,上面的圖javascript的紅框上面有java,裡面也是有類似的設定,但文字描述有一點不一樣,Auto activation triggers for JavaDoc,預設也是@#,Java的註解有三種,它的註解只有用在/**‧‧‧*/的時候,在裡面打@和#都會提示,但這裡的javascript我試不出來

2016年4月16日 星期六

12c 的 OFFSET (DML 十四)

取出資料的前幾筆或中間的資料(就是MS SQL的top),終於在12c有了,官網連結,搜尋「OFFSET」可找到語法,再搜尋「Row Limiting: Examples」,有範例可參考

要放在SELECT的最下面,複習一下語法:
1.SELECT:必要
2.FROM:必要
3.WHERE:選擇使用
4.GROUP BY :選擇使用
5.HAVING:有GROUP BY才可用
6.ORDER BY:選擇使用
7.OFFSET:選擇使用


語法如下(自己想的,不一定正確,看下方的紅字):
[OFFSET n [ROW|ROWS]] FETCH [FIRST|NEXT] n [PERCENT] [ROW|ROWS] [ONLY|WITH TIES]

※最後的PERCENT和ONLY要寫其中一個

※筆數是從0開始的

※OFFSET不指定,預設是 OFFSET 0 [ROW|ROWS],表示從第0筆開始

※OFFSET後的數字給負的,都表示0;如果給null或大於等於返回的行數,那就沒有結果返回

※FETCH [FIRST|NEXT] 表示取出幾筆資料,官方說不指定會將全部的結果返回,但我試的結果,不加就是編譯錯誤

※PERCENT是取百分筆用的(官方寫兩種,都一定是給數字,我懷疑它要如何分辯),如果給負數視同0;給null沒有結果返回
官方說如不給數字,預設是1,但我試的結果是編譯錯誤

※ONLY|WITH TIES兩者選者其一,但官方有說使用WITH TIES要配合ORDER BY使用,不然沒有結果會返回,但我試的結果和ONLY一樣

※最後一定要有 ROW ONLY、ROW WITH TIES、ROWS ONLY、ROWS WITH TIES 這四者其中之一語法才是正確的


※範例

SELECT * FROM emp OFFSET 10 ROWS FETCH NEXT 2 ROW ONLY;
SELECT * FROM emp OFFSET 10 ROWS;
SELECT * FROM emp FETCH FIRST 3 ROWS ONLY;
SELECT * FROM emp FETCH NEXT 10 PERCENT ROWS ONLY;
SELECT * FROM emp FETCH FIRST 10 PERCENT ROWS WITH TIES;

※第一條SQL表示忽略前10筆,取兩筆記錄,所以顯示第11和12筆

※第二條SQL表示從第11筆之後開始到最後

※第三條SQL表示取出前三筆

※第四、五條SQL都表示取10%的記錄,因為全部有14筆,所以是1.4
官方說小數會被截斷,可是我試的結果並不是,也不會四捨五入,直接進1,結果是2條記錄

2016年4月15日 星期五

SEQUENCE、INDEX (DDL 六)

※SEQUENCE

其他的資料庫有自動流水號的功能,而Oracle在11g(含)之前都沒有,之前都一直用這個Sequence


※增刪改查

CREATE SEQUENCE xxx;
CREATE SEQUENCE ooo START WITH 5;
CREATE SEQUENCE zzz START WITH -5 MINVALUE -2000;
CREATE SEQUENCE yyy INCREMENT BY -2000;
CREATE SEQUENCE aaa MAXVALUE 2000 MINVALUE 1 INCREMENT BY 40 CACHE 48 CYCLE;
    
ALTER SEQUENCE aaa MAXVALUE 2500;
    
DROP SEQUENCE aaa;
    
SELECT xxx.NEXTVAL from dual;
SELECT ooo.NEXTVAL from dual;
SELECT zzz.CURRVAL from dual;
    
SELECT * from USER_SEQUENCES

※設定完用NEXTVAL和CURRVAL,可以得知下一個和目前的sequence是多少,但剛創建完一定要執行過NEXTVAL後,才能執行CURRVAL



※選項

官方文件:創建修改刪除
可以得知創建總共有16種選項,修改有15種(少了創建的START WITH)

以下的預設值沒特別寫就是NOxxx:
START WITH:這個選項ALTER沒有,是設定初始值的,當然不會有
    預設值正數是MINVALUE,負數是MAXVALUE
INCREMENT BY:一次增加多少,正數往上增加;負數往下,預設是1
MAXVALUE/NOMAXVALUE:設定最大值,預設是10的28次方減1
MINVALUE/NOMINVALUE:設定最小值,預設是0,可以設到10的27次方減1
CYCLE/NOCYCLE:要不要循環,不環循到臨界點的時候就會出錯誤訊息
CACHE/NOCACHE:預設是20,用完了再去資料庫要20,最主要是要降低和資料庫字典要值的次數,可以增加效能

以下六個我無法理解:
ORDER/NOORDER
KEEP/NOKEEP
SESSION/GLOBAL:預設是GLOBAL



※注意

設定CACHE容易出現的錯誤:
CREATE SEQUENCE aaa MAXVALUE 2000 MINVALUE -200 INCREMENT BY -40 CACHE 48 CYCLE;

如果沒設定好會出「ORA-04013: 要放到 CACHE 中的數目必須小於一個循環週期」的錯
官方有個公式(CEIL (MAXVALUE - MINVALUE)) / ABS (INCREMENT)
如果CACHE大於這個數字就會報這個錯(等於不會)
CEIL是天花板,就是往上(正數);ABS就是絕對值(絕對是正數的值)
以這個例子就是
(CEIL(2000-(-200))) / ABS(-40)
2200/40 = 55
所以只要CACHE設定超過55就會報這個錯



※流水號

流水號終於在12c這一版增加了


CREATE TABLE t1 (
    id NUMBER GENERATED AS IDENTITY,
    name VARCHAR2(10)
);
    
CREATE TABLE t2 (
    id NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 10),
    name VARCHAR2(10)
);

※第一條SQL是不加選項,什麼都用預設的

※要加選項就用第二條SQL



※INDEX

官網連結
主要是加快查詢速度用的

語法:
CREATE [UNIQUE|BITMAP] INDEX INDEX ON 表(欄[,欄...]) [USABLE|UNUSABLE]
最後面什麼都不打,預設是USABLE,表示可以用的意思

使用sys登入後,下「SET AUTOTRACE ON;」(要關掉改OFF即可)

※要注意每次執行完SQL語句都要按一次上面的按鈕才會更新

※如果用sqlplus,還可以看到更詳細的資訊,如時間…等

※執行最後一條SQL後,紅框的FULL會變成ROWID,ROWID是效能最快的;FULL指的是一行一行去掃描

※由於INDEX在工作時,我從來沒用過,不知會出什麼問題,只能提供官網連結(上面有提供了),拉到最下面也有很多範例,還有一個我覺得寫的很好的文章

※如要刪除,就下「DROP INDEX index名稱」

VIEW、SYNONYM (DDL 五)

※VIEW

官網連結
使用View時,在12c預設是沒有權限的
要用有權限的帳號登入後,下「GRANT CREATE VIEW TO 帳號;」

view的功能就是將很複雜的SQL變的很簡單,讓大家使用,所以寫view的SQL都很強,它是連到其他的table,所以其他的table改變,它也會跟著變



※範例

CREATE OR REPLACE NOFORCE VIEW v_xxx
AS
SELECT deptno dno, empno eno, dname, ename 
FROM emp natural join dept;

※一定要打AS,不能打IS

※FORCE/NOFROCE:預設是NOFORCE,所以上面的範例NOFORCE可以不打
FORCE表示連到的表不存在,也要創建view,雖然創建好了,但是還是不能SELECT
可能是多人開發時,有些table還沒創建好,但你負責的部分是要寫view,如果沒這個選項你就沒辦法寫了

※AS下面就是隨個人發揮,寫簡單的也可以,只是沒意義,欄位可以打別名

※OR REPLACE也是選項,有打的話,發現同名稱會覆蓋

※刪除view,就下「DROP VIEW v_xxx;」,沒有PURGE的選項,因為本來就是連別的表



※查詢view

SELECT * FROM tab WHERE TABTYPE = 'VIEW';
SELECT * FROM user_views;

※TAB是所有的TABLE,只是看大概的訊息

※更詳細的就要看USER_VIEWS了



※view的增刪改

增刪改當然是針對原表,而view的增刪改是有限的,這樣看你怎麼樣下SQL了
以一張表為例
正常情況和一般增刪改一樣
可是如果表裡有not null、PK的欄位,但你下SQL並沒有把它SELECT出來,所以新增就沒辦法了,修改當然也不能改成null,刪除如果有FK、PK的關係有是有可能刪不了

多張表的情況也類似這樣,反正它只能儘量增刪改
要以下出來的條件為準,view只是一個連結,而這個連結可以讓你增刪改,不能的話就要看你怎麼下SQL了

可以使用delete,但不能使用truncate



※WITH READ ONLY

CREATE OR REPLACE NOFORCE VIEW view_test
AS
SELECT * FROM EMP WHERE deptno = 30 AND job = 'SALESMAN'
WITH READ ONLY;

※加上這個語句就只能查詢而已



※WITH CHECK OPTION [CONSTRAINT xxx]

CREATE OR REPLACE NOFORCE VIEW view_test
AS
SELECT * FROM EMP WHERE deptno = 30 AND job = 'SALESMAN'
WITH CHECK OPTION;

※加上這個語句就不能修改where的欄位,也不能新增;但可以刪除

※CONSTRAINT是給一個約束名稱,不給系統會幫你產生

※以下這兩個都不能成功
UPDATE view_test SET job = 'xxx' WHERE empno = 7499;
INSERT INTO view_test(empno, ename)values(9999, 'BRUCE');



※SYNONYM

SYNONYM翻譯成代名詞,官網連結,簡單來說就是一個table的別名,這個別名等同原來的table,所以也可以增刪改查,而且原來的表也會更動


使用SYNONYM必須用sys登入才有權限
CREATE [PUBLIC] SYNONYM 代名詞名稱 FOR 帳號.表;
CREATE SYNONYM bruce FOR ooo.EMP;

※因為是用sys創建的,所以select * from bruce,只有sys帳號才看得到,如果想讓大家都看到,就要使用CREATE PUBLIC

※完成後也能在USER_SYNONYMS這張表找到

※刪除就下「DROP SYNONYM 代名詞名稱;」

2016年4月14日 星期四

JSP 的指令元素(taglilb)和指令元素與動作元素的include (JSP 2.x 三)

※指令元素(taglilb)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="xxx" tagdir="/WEB-INF/tags" %>

※uri和tagdir都是取得tag的地方

※uri是別人寫好而且公認的標籤,如JSTL;而tagdir是自己寫的,裡面寫放tag的路徑
等寫到JSTL就會有感覺了

※prefix是標籤開頭用的,如c:,xxx:



※指令元素與動作元素的include

@page 有個include,屬性只有file,指定要包含的路徑
但後面還會寫動作元素,裡面也有個include,兩個很像,這篇要介紹不同的地方

<jsp:include>是動作元素,屬性變成page,也是指定要包含的路徑,但它還有另外一個屬性flush,是在問說buffer滿的時候要不要清空,預設是false
先準備三個頁面,副檔名分別是txt、html、jsp

※text.txt

<%@ page pageEncoding="UTF-8"%>
<br />我是text<br />
<%=new Date()%><br />



※html.html

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <br />我是HTML<br />
        <%=new Date()%><br />
    </body>
</html>

※txt和html先不用include,看單一的結果:

※可以看出txt編碼沒有用,而html我將全部的編碼刪除,run起來都不會出亂碼



※jsp.jsp

<%@ page pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        我是jsp<br />
        <%=new Date()%><br />
    </body>
</html>



※test.jsp

<%@ include file="/text.txt" %><br />
<%@ include file="/html.html" %><br />
<%@ include file="/jsp.jsp" %>
---------------------------------------------------<br />
<jsp:include page="/text.txt" /><br />
<jsp:include page="/html.html" /><br />
<jsp:include page="/jsp.jsp" />

※結果:

※虛線上面是指令元素;下面是動作元素

※指令元素的jsp和html不加編碼會出亂碼;動作元素不會

※指令元素會將全部的內容include才進行編譯;但並不完全正確,如果是這樣的話,那page除了import可以寫多行,其他都不行,如果include進來,以我上面的做法有多行一樣的,那就會500才對,可是結果並沒有,而且編碼設定真的有效果

※動作元素每一支都會先編譯才include進來(可以看變成servlet的目錄,指令元素永遠只有一個;動作元素會有多個,但只有jsp才會轉成servlet)
所以指令元素不管變數加在txt、html、jsp都會錯誤,而動作元素不會

2016年4月10日 星期日

JSP 的指令元素 (page) (JSP 2.x 二)

參考JSP2.3的spec的JSP.1.10,上一篇有提供連結,語法如下
<%@ directive { attr=”value” }* %>

directive 有三種:page、tablib、include



※page

屬性有15種
{ language=”scriptingLanguage”}
{ extends=”className”}
{ import=”importList”}
{ session=”true|false”  }
{ buffer=”none|sizekb” }
{ autoFlush=”true|false”  }
{ isThreadSafe=”true|false”  }
{ info=”info_text” }
{ errorPage=”error_url” }
{ isErrorPage=”true|false” }
{ contentType=”ctinfo”}
{ pageEncoding=”peinfo”}
{ isELIgnored=”true|false” }

2.1(含)後又增加這兩個
{ deferredSyntaxAllowedAsLiteral=”true|false”}
{ trimDirectiveWhitespaces=”true|false”}


※除了import以外,<%@ page %>可以寫很多行,但屬性名不能重覆,否則會出「Page directive must not have multiple occurrences of pageencoding」的錯

※以下用2.3版測試


※contentType、pageEncoding

<%@ page language="java" contentType="application/msword; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <%
            response.setHeader("Content-Disposition", "Attachment; filename=xxx.doc");
        %>
        <table border="1">
            <tr><td>ascii</td></tr>
            <tr><td>氣气気</td></tr>
        </table>
    </body>
</html>

※contentType="text/html; charset=UTF-8"
在tomcat資料夾下的webapps\examples\WEB-INF\web.xml可以複製

※MIME預設就是text/html

※MIME是text/plain就會變成純文字檔,所以一點顏色都沒有,亂打會出現下載視窗

※MIME是application/msword,我用IE11會出錯,但用chrome是ok的,一樣會出現下載視窗,檔名依瀏覽器不同會不一樣,內容編碼吃的是meta的編碼

※如果要控制下載的檔名,可用response那一行,參考這裡

※charset 參考Servlet第二篇



※errorPage、isErrorPage

※test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page errorPage="error.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <% int a = 1 / 0;%>
    </body>
</html>

※指定errorPage後,如果此網頁有錯,就會跳轉,且網址不變



※error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page isErrorPage="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>我錯了</h1>
        <%
            response.setStatus(200);
        %>
        <%=exception.getMessage()%>
    </body>
</html>

※isErrorPage是true,才能使用隱函物件exception

※網頁錯誤後,就會跳轉到error.jsp,多按幾次重整會發現有時候成功,有時候500,所以增加response那一行,200代表ok,都沒問題


還有一種方法是用web.xml的設定方式,在Servlet六的錯誤頁面有寫,但要注意IE有可能會有問題(我用IE11預設不行),將下面的勾取消即可


它預設有勾,它勾起來我反而不易懂好不好
上面還有「如果IE不是預設的網頁瀏覽器,請告訴我」,不想用的可取消


※language

文件寫的好長,我懶的看,反正寫java就對了


※extends

※xxx.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page extends="pkg.JSPDad"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <%System.out.println("name=" + getName()); %>
        <%System.out.println("name2=" + getName2()); %>
        <h1>我跳</h1>
    </body>
</html>

※extends的類別,一定要繼承HttpServlet,不然會出「Unable to compile class for JSP」的錯

※沒加extends那一行時,getName()和getName2()當然不能用,「我跳」當然也有在畫面上
我一加extends那一行,就會跳到JSPDad的doGet方法,所以「我跳」沒看到很合理,但getName()和getName2()在控制台也沒有看到,不知道為什麼?


※JSPDad.java

public class JSPDad extends HttpServlet {
    private String name = "xxx";
    public static String name2 = "ooo";
    // setter/getter...
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get");
        // resp.getWriter().println("<html><head></head><body><h1>Yeah!</h1></body></html>");
        // req.getRequestDispatcher("/first.jsp").include(req, resp);
        resp.sendRedirect(req.getContextPath() + "/first.jsp");
    }
}

※父類別一定要覆寫doGet方法,覆寫doPost沒用,沒覆寫就會405

※first.jsp自己隨便寫,是可以跳轉的

※如果跳轉又寫xxx.jsp會變成無限迴圈


※import

和java的import一樣,可以寫很多行或者寫一行,用「,」隔開,重覆import也是可以的


※session

可不可以使用session,預設是true
上一篇有說9種隱含物件,它就是其中一種,如果這個選項設false,那這一頁就不能使用session了


※buffer、autoFlush

buffer為設定buffer大小,預設是8kb
autoFlush為buffer滿時,是否自動強制輸出,預設是true

如果超出buffer大小
autoFlush設false,會出「IOException: Error: JSP Buffer overflow」
autoFlush設true,還是可以正常輸出,內容也不會變少

buffer設定成0kb或none
autoFlush設false,會出「jsp.error.page.badCombo」
autoFlush設true,還是可以正常輸出,內容也不會變少


※isThreadSafe

在Servlet2.4已過時了,tomcat5.5、Servlet就是2.4,而JSP是2.0,看tomcat連結
預設是true,表示此jsp是安全的,一次允許多個request
如果是false,則一次只允許一個request

※info

設定訊息,可以透過getServletInfo()取得
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" info="xxx"%>
<html>
    <head></head>
    <body><%=getServletInfo()%></body>
</html>


※isELIgnored

要不要忽略EL,就是長「${}」的東東,以後會講



※以下兩個屬性是2.1(含)才有的

※deferredSyntaxAllowedAsLiteral

是否允許在頁面上有「#{}」,預設不允許,所以一打會出現編譯錯誤(Spring的EL就長這樣)

※官方文件有寫說page的作者說,在web.xml寫如下的設定可以覆蓋
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <deferred-syntax-allowed-as-literal>false</deferred-syntax-allowed-as-literal>
    </jsp-property-group>
</jsp-config>

※我試的結果根本沒覆蓋


※trimDirectiveWhitespaces

※jsp頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="false" isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
</head>
    
<body>
    <% String s = "s"; %>
    <b>hey man!</b>
    ${user}
    <%=s%>
</body>

※這個要在網頁按右鍵,檢視-->原始檔才看得出來,如下:

※上面的圖是設成false或沒設時,下面的圖是true

※官方文件有寫說page的作者說,在web.xml寫如下的設定可以覆蓋
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <trim-directive-whitespaces>true</trim-directive-whitespaces>
    </jsp-property-group>
</jsp-config>

※我在web.xml全不寫當然是ok的,但奇怪的是我把這裡改成false,我試的結果還是run的好好的,根本就沒覆蓋啊!

完整性約束的型態 (DDL 三)

參考官網,用法和範例可參考這連結,總共分成六種:
1.NOT NULL:禁止放null

2.UNIQUE:同一欄位只能唯一,但允許放null

3.PRIMARY KEY(PK):NOT NULL + UNIQUE

4.FOREIGN KEY(FK):欄位指定FK後,表示此欄位的值必需是另外一張表的欄位值的其中之一

5.CHECK:符合指定的條件

6.REF:參考到另外一個物件,個人覺得這個比較不像約束,比較像自定型態,很多書寫完整性約束時也沒有提到這個,不過官網有就是了

※NOT NULL只能放在宣告欄位的最後面,其他的除了這種方式,還有一種是為約束命名的寫法,這個是官方說的,可是FK我試的結果只能用約束命名的寫法(而且只能使用CONSTRAINT獨立一行),官網也沒有提供不寫約束名稱的範例

※以下以這個範例來練習,先寫沒有約束名稱的寫法
DROP TABLE xxx PURGE;
CREATE TABLE xxx (
    id number(5) PRIMARY KEY,
    name varchar2(20) UNIQUE,
    color varchar2(10) NOT NULL,
    price number(5,2) DEFAULT 0 CHECK(price BETWEEN 0 AND 1000),
    make_date timestamp DEFAULT sysdate UNIQUE
);
    
    
CREATE TABLE ooo (
    oid number(5) PRIMARY KEY,
    oname varchar2(20) UNIQUE,
    xid number(5),
    CONSTRAINT fk_xid FOREIGN KEY(xid) REFERENCES xxx(id)
);

※DEFAULT一定要在約束前面,如果有DEFAULT,INSERT時可以不塞值


※NOT NULL

INSERT INTO xxx(id, color) VALUES (1, null);
INSERT INTO xxx(id) VALUES (1);

※預設不打就是null,所以這兩條SQL是一樣的

※因為color是null,所以會出「ORA-01400: 無法將 NULL 插入 ("帳號"."XXX"."NAME")」的錯



※UNIQUE

INSERT INTO xxx(id, name, color, price) VALUES (1, 'apple', 'red', 50);
INSERT INTO xxx(id, name, color, price) VALUES (2, 'apple', 'blue', 40);

※第一條SQL新增成功,但第二條的name值一樣,所以會出「ORA-00001: 違反必須為唯一的限制條件」的錯

※null可以重覆,官網有說明



※PRIMARY KEY

一筆記錄的唯一值,所以是NOT NULL + UNIQUE



※CHECK

INSERT INTO xxx(id, name, color, price) VALUES (1, 'apple', 'red', 1002);

※因為price的範圍是0~1000,1002已經超過了,所以會出「ORA-02290: 違反檢查條件 (C##SCOTT.SYS_C0010287)」的錯



※FOREIGN KEY

一定要有兩張表而且FK對應的欄位必需有UNIQUE(所以PK也可以),而且型態也要一樣

只要欄位有FK,那就表示它的值有多筆,對應到另外一個table的欄位值(除非另外一個table的欄位值只有一種)
因為這樣的原因,所以刪除時,預設也必須先刪除子項(FK)的欄位,才能刪除父項(PK)的欄位


INSERT INTO xxx(id, name, color) VALUES (1, 'aaa', 'red');
INSERT INTO xxx(id, name, color) VALUES (2, 'bbb', 'blue');
    
    
INSERT INTO ooo(oid, oname, xid) VALUES (2, 'qoo', 3);

※xxx新增兩條SQL,而ooo的xid是對應到xxx的id,而xxx的id值,全部的值有1和2,所以ooo的xid不塞1或2,就會發生「ORA-02291: 違反完整性限制條件 (C##SCOTT.FK_XID) - 找不到父項索引鍵」的錯

※null是可以的



※REF

-- 1.新增TYPE
DROP TYPE aaa;
CREATE TYPE aaa AS OBJECT (
    p1 varchar2(40),
    p2 varchar(2)
);
    
-- 2.新增Table,並使用REF型態
DROP TABLE bbb PURGE;
CREATE TABLE bbb (
    id number, 
    ref_name REF aaa
);
    
-- 3.新增另一張Table,並引用aaa TYPE,順便塞值
DROP TABLE table_a PURGE;
CREATE TABLE table_a OF aaa;
INSERT INTO table_a VALUES('1', 'a');
INSERT INTO table_a VALUES('2', 'b');
    
-- 4.新增資料
INSERT INTO bbb(id, ref_name)VALUES(1, 
    (SELECT REF(t) FROM table_a t WHERE P1 = '1')
);
INSERT INTO BBB(id, ref_name)VALUES(2, 
    (SELECT REF(t) FROM table_a t WHERE P1 = '2')
);

※主要是2的bbb表,它要使用一個TYPE,所以1才要新增TYPE
4要新增時,不知道怎麼塞值,所以3就引用的aaa TYPE
所以使用REF是不能直接在裡面塞值的,要像3這樣引用才可以

※修改可參考PL/SQL 三十三



※以上的6種約束可以混用,用空格隔開如「NOT NULL UNIQUE」,但不是全部都可以,詳情要看官網的說明,例如PRIMARY KEY UNIQUE就不行




※有約束名稱的寫法

CREATE TABLE xxx (
    id number(5),
    name varchar2(20),
    color varchar2(10) NOT NULL,
    price number(5,2) DEFAULT 0,
    make_date timestamp DEFAULT sysdate UNIQUE,
    
    CONSTRAINT pk_id PRIMARY KEY(id),
    CONSTRAINT uk_name UNIQUE(name),
    CONSTRAINT ck_price CHECK(price BETWEEN 0 AND 1000)
);
    
    
CREATE TABLE xxx (
    id number(5) CONSTRAINT pk_id PRIMARY KEY,
    name varchar2(20) CONSTRAINT uk_name UNIQUE,
    color varchar2(10) NOT NULL,
    price number(5,2) DEFAULT 0 CONSTRAINT ck_price CHECK(price BETWEEN 0 AND 1000),
    make_date timestamp DEFAULT sysdate UNIQUE
);

※PK、UNIQUE、CHECK都可以獨立成一行或宣告欄位的最後面

※獨立一行還可以設定多個欄位,下面會介紹



※PK、FK、UNIQUE多個欄位

DROP TABLE xxx PURGE;
CREATE TABLE xxx (
    id number(5),
    name varchar2(20),
    color varchar2(10) NOT NULL,
    price number(5,2) DEFAULT 0 UNIQUE,
    make_date timestamp DEFAULT sysdate UNIQUE,
    
    CONSTRAINT pk_id_name PRIMARY KEY(id, name),
    CONSTRAINT uk_name UNIQUE(name),
    CONSTRAINT ck_price CHECK(price BETWEEN 0 AND 1000)
);
    
DROP TABLE ooo PURGE;
CREATE TABLE ooo (
    oid number(5),
    oname varchar2(20),
    xid number(5),
    xname varchar2(20),
    
    CONSTRAINT pk_oid_xid PRIMARY KEY(oid, xid),
    CONSTRAINT fk_xid_xname FOREIGN KEY(xid, xname) REFERENCES xxx(id, name),
    CONSTRAINT uk_oname_xid UNIQUE(oname, xid)
);

※主要是看ooo表,而FK對應的表欄位兩個欄位也要有UNIQUE(所以PK也可以)



※新增/刪除約束

-- 1
ALTER TABLE xxx MODIFY(color varchar2(25));
    
-- 2
ALTER TABLE ooo DROP CONSTRAINT fk_xid;
ALTER TABLE xxx DROP CONSTRAINT pk_id;
ALTER TABLE xxx ADD CONSTRAINT pk_id PRIMARY KEY(id);
ALTER TABLE ooo ADD CONSTRAINT fk_xid FOREIGN KEY(xid) REFERENCES xxx(id);
    
-- 3
ALTER TABLE xxx DROP CONSTRAINT ck_price;
ALTER TABLE xxx ADD CONSTRAINT ck_price CHECK(price BETWEEN 500 AND 2000);
    
-- 4
ALTER TABLE xxx DISABLE /*ENABLE*/ CONSTRAINT ck_price;

※1是NOT NULL用的

※2我在官網沒有看到修改約束和修改約束名稱的功能,所以只好先刪除再新增了

※2和3是PK、FK、CHECK

※4是將約束啟用/停用的功能

※因為有這個功能,所以有些地方是先新增表,創建完了才用這種語法加一些限制條件



※FK還有重要的功能,下一篇再寫

2016年4月9日 星期六

ALTER、COMMENT (DDL 二)

這一篇還是DDL,所以ALTER、COMMENT執行完也會將前面沒有commit的進行commit

前一篇是針對表的增刪改,下面是針對表裡的欄位的增刪改
ALTER TABLE <table> ADD <field> <type> [default];-- 增加一個欄位
ALTER TABLE <table> ADD (<field> <type> [default], <field> <type> [default]);-- 增加多個欄位
    
ALTER TABLE <table> DROP COLUMN <field>;-- 刪除一個欄位
ALTER TABLE <table> DROP (<field>, <field>);-- 刪除多個欄位
    
ALTER TABLE <table> MODIFY <field> <type> [default] [not null];-- 修改欄位,不包括欄位重命名
ALTER TABLE <table> RENAME COLUMN <old_field> TO <new_field>;-- 欄位重命名用這個

官網連結

※删除约束可用「ALTER TABLE <table> Drop CONSTRAINT <約束名稱>;
※增加UK:ALTER TABLE <table> ADD CONSTRAINT <約束名稱> UNIQUE(欄位);
※增加PK:ALTER TABLE <table> ADD CONSTRAINT <約束名稱> PRIMARY KEY(欄位);
※增加複合主鍵:前面和「增加PK」一樣,最後是PRIMARY KEY(欄位,欄位...);
※增加FK:ALTER TABLE <table> ADD CONSTRAINT <約束名稱> FOREIGN KEY(欄位) REFERENCES 另一張表名稱(另一張表欄位);


※UNUSED

如果資料太多,會刪的很慢,所以可以先設定成不使用,等到沒什麼人用資料庫時再刪,例如凌晨時再刪

變成不使用的狀態後,SELECT看不到不使用的欄位


ALTER TABLE xxx SET UNUSED COLUMN price; -- 將一個欄位設為不使用
ALTER TABLE xxx SET UNUSED(name); -- 將一個欄位設為不使用
ALTER TABLE xxx SET UNUSED(name, id); -- 將多個欄位設為不使用
ALL_UNUSED_COL_TABS -- 這張表可以得知表裡有幾個不使用欄位
ALTER TABLE xxx DROP UNUSED COLUMNS; -- 刪除不使用的欄位

※官網我沒有看到恢復UNUSED變成使用狀態,所以小心使用

※如果想要恢復還可以用下面要講的VISIBLE



※VISIBLE/INVISIBLE

這個功能是Oracle 12c才有的,可以用V$VERSION這張表,看資料庫版本

在新增時,如果欄位名稱不夠,會編譯錯誤,而這個功能可以讓SELECT、DESC時,看不到這個欄位,新增也不需要用到這個欄位,它會直接給null


ALTER TABLE xxx MODIFY(name invisible);
    
CREATE TABLE xxx (
    id number(5),
    name varchar2(20) INVISIBLE
);

※第一條SQL是讓name欄位看不見,要回復只要改成VISIBLE即可

※也可以像第二條SQL那樣,在新增表時就使用

※雖然看不見欄位,但用下面要講的COMMENT,USER_COL_COMMENTS 這張表就能看到了



※COMMENT

就是為表和欄位增加註解,讓人家知道這個表和欄位是做什麼用的


COMMENT ON TABLE <table> IS 'xxx';
COMMENT ON COLUMN <table>.<field> IS 'ooo';
    
SYS.USER_TAB_COMMENTS -- 看所有表的註解
SYS.USER_COL_COMMENTS -- 看所有欄位的註解

CREATE、DROP、RENAME、TRUNCATE、回收表 (DDL 一)

※DDL

之前講的都是DML(資料處理語言),針對表的增刪改查,做完要commit,其他的session才會看的到
而DDL(資料定義語言),是創建、刪除、修改表,把它想成執行完會自動commit,所以待會講到CREATE、DROP、RENAME、TRUNCATE、FLASHBACK、PURGE(增刪改)時,假設有做update表的動作,但沒有commit,只要一執行DDL,那就會自動commit了,這點要注意


※新增

CREATE TABLE chess (
    id number(5),
    name varchar2(20),
    price number(5,2) DEFAULT 0,
    make_date1 date DEFAULT sysdate,
    make_date2 timestamp,
    pic clob
);

※chess要表名稱,自己想一個,「()」裡最左邊是欄位名稱,自己想名字,右邊為資料型態

官網連結,內鍵的有23種

※常用的就是下面那幾種了
.number:
可用int和float代替,number(5,2),5為全部位數,不包括小數點; 2為小數點位數
所以123.45是ok的;number(3, 0)等同number(3),沒有小數點的意思,上面官網連結的Table 2-2有NUMBER的說明,已經很清楚了

.varchar、varchar2、char:
char(5)就是長度是5,varchar2(5)就是最多長度是5,如果有個值是abc,那char取出來後面會包括兩個空格,varchar和varchar2不會,所以才叫var(變動)
varchar和varchar2目前都一樣,官方推薦用varchar2

.date、timestamp:
date年月日;timestamp年月日時分秒

.clob、blob:
c就是character,所以放的是文字;b就是byte,所以放的是圖片

.nXXX:
如nchar、nvarchar2、nclob,主要是存中文字,因為你輸入長度3,它可能內部會將你輸入的長度乘2或3,看編碼而定

※複製表

CREATE TABLE xxx AS SELECT * FROM emp;
CREATE TABLE xxx AS SELECT * FROM emp WHERE 1=0;

※也就是從emp這張表整個複製一份出來變成xxx

※第二條SQL的where永遠不成立,所以只會複製表結構,裡面沒有內容,算是一種運用吧!

※要注意CONSTRAINT 不複製,所以PK、FK都沒有,過幾篇會說明

※AS一定要打,而且不能打IS



※修改

RENAME xxx TO ooo;

※xxx是舊表名,ooo是新表名,就算有PK、FK也可以改



※刪除

DROP TABLE chess;
DROP TABLE chess PURGE;

※兩種方式都可以,差別在下面的資源回收表有說



※清空表

TRUNCATE TABLE xxx;
DELETE FROM xxx;

※TRUNCATE為DDL;DELETE為DML

※DDL比較快;但DML因為還沒commit,所以多一個反悔的機會



※查看表結構

DESC ooo;

※只能看到欄位名稱、欄位類型、是否接受null



※查看目前帳號的表

SELECT * FROM tab;

※資料字典分為兩類
.動態資料字典:隨著資料庫運行而更新的表,通常以「V$」開頭

.靜態資料字典又分成以下三種:
user_開頭:目前帳號的表
all_開頭:目前帳號可以存取的表
dba_開頭:所有的表,必需有權限



※回收表

就是將表刪除後,類似Windows的資源回收桶,還有還原的機會


DROP TABLE xxx;--1
SELECT * FROM tab;--2
SELECT * FROM recyclebin;--3
FLASHBACK TABLE xxx TO BEFORE DROP;--4

※第一步刪除完後,看第二步的表,會發現TNAME多一個「BIN$」開頭,「==$0」結尾的,表示已經到回收表裡了

※第三步的表就是回收表,從ORIGINAL_NAME也會發現剛剛刪除的xxx,如果有多個,那就表示之前刪除了很多,剛好名稱也是xxx

※如果名稱有多個,它還會幫我們多兩個記錄,
「SYS_IL」開頭,「$$」結尾和「SYS_LOB」開頭,「$$」結尾的
而且CREATETIME時間欄位和刪除的表一樣

※第四步使用這種語法能恢復表,它會恢復最接近目前時間且名稱和ORIGINAL_NAME一樣的(例如有三筆資料:1分鐘前刪的、2分鐘前刪的、3分鐘前刪的,會恢復1分鐘前刪的)

※恢復完成後,第二和第三步的表都會少一行

※如果不想進資源回收表,就使用DROP TABLE xxx PURGE;



※刪除回收表

回收表沒辦法用DELETE和TRUNCATE刪的,要用以下的語法


PURGE TABLE xxx;
PURGE recyclebin;

※第一條SQL是刪除一筆,如果有「SYS_IL」開頭,「$$」結尾和「SYS_LOB」開頭,「$$」結尾的,而且CREATETIME時間欄位和刪除的表一樣的,也會一起刪除
刪除的是離目前時間最遠的那一筆(例如有三筆資料:1分鐘前刪的、2分鐘前刪的、3分鐘前刪的,會刪除3分鐘前刪的)

※一筆一筆刪除太累了,所以第二條SQL是清空整個回收表用的