1.集合操作
学习oracle中集合操作的有关语句,掌握union,union all,minus,interest的使用,能够描述结合运算,并且能够将多个查询组合到一个查询中去,能够控制行返回的顺序。
包含集合运算的查询称为复合查询。见表格1-1
表1-1
Operator         Returns         content
UNION         由每个查询选择的所有不重复的行          并集不包含重复值
UNION ALL         由每个查询选择的所有的行,包括所有重复的行         完全并集包含重复值
INTERSECT         由每个查询选择的所有不重复的相交行          交集
MINUS         在第一个查询中,不在后面查询中,并且结果行不重复          差集

所有的集合运算与等号的优先级相同,如果SQL语句包含多个集合运算并且没有圆括号明确地指定另一个顺序,Oracle服务器将以从左到右的顺序计算。你应该使用圆括号来明确地指定带另外的集合运算的INTERSECT (相交) 运算查询中的赋值顺序。
Union all 效率一般比union高。
1.1.union和union all
UNION(联合)运算 
UNION运算返回所有由任一查询选择的行。用UNION运算从多表返回所有行,但除去任何重复的行。 
原则 :

􀂃?被选择的列数和列的数据类型必须是与所有用在查询中的SELECT语句一致。列的名字不必相同。 
􀂃?联合运算在所有被选择的列上进行。 
􀂃?在做重复检查的时候不忽略空(NULL)值。 
􀂃?IN运算有比UNION运算高的优先级。 
􀂃?在默认情况下,输出以SELECT子句的第一列的升序排序。 

全联合(UNION ALL)运算 
用全联合运算从多个查询中返回所有行。 
原则 

􀂃?和联合不同,重复的行不被过滤,并且默认情况下输出不排序。 
􀂃?不能使用DISTINCT关键字。 
使用:
Select statement union | union all Select statement;

1.2.intersect交集操作
相交运算 
用相交运算返回多个查询中所有的公共行。 无重复行。
原则 

􀂃?在查询中被 SELECT 语句选择的列数和数据类型必须与在查询中所使用的所有的 SELTCT 语句中的一样,但列的名字不必一样。 
􀂃?相交的表的倒序排序不改变结果。 
􀂃?相交不忽略空值。 
使用:
Select statement intersect all Select statement;

1.3. minus差集操作
相减运算 
用相减运算返回由第一个查询返回的行,那些行不出现在第二个查询中 (第一个SELECT语句减第二个SELECT语句)。 
原则 

􀂃?在查询中被SELECT语句选择的列数和数据类型必须与在查询中所使用的所有的SELTCT语句中的一样,但列的名字不必一样。 
􀂃?对于MINUS运算,在WHERE子句中所有的列都必须在SELECT子句中。 


集合运算的原则
?在两个SELECT列表中的表达式必须在数目上和数据类型上相匹配
?可以用圆括号改变执行的顺序
?ORDER BY子句:–只能出现在语句的最后–从第一个SELECT语句接收列名、别名,或者位置记号

注:?除了UNION ALL,重复行自动被清除
?在结果中的列名是第一个查询中出现的列名
?除了UNION ALL,默认情况下按升序顺序输出
2.exists和not exists的使用
2.1. exists的使用
Exists用于只能用于子查询,可以替代in,若匹配到结果,则退出内部查询,并将条件标志为true,传回全部结果资料,in不管匹配到匹配不到都全部匹配完毕,使用exists可以将子查询结果定为常量,不影响查询效果,而且效率高。如查询所有销售部门员工的姓名,对比如下:
IN is often better if the results of the subquery are very small
When you write a query using the IN clause, you're telling the rule-based optimizer that you want the inner query to drive the outer query.
When you write EXISTS in a where clause, you're telling the optimizer that you want the outer query to be run first, using each value to fetch a value from the inner query.
In many cases, EXISTS is better because it requires you to specify a join condition, which can invoke an INDEX scan. However, IN is often better if the results of the subquery are very small. You usually want to run the query that returns the smaller set of results first.


In和exists对比:
若子查询结果集比较小,优先使用in,若外层查询比子查询小,优先使用exists。因为若用in,则oracle会优先查询子查询,然后匹配外层查询,若使用exists,则oracle会优先查询外层表,然后再与内层表匹配。最优化匹配原则,拿最小记录匹配大记录。
使用in
select last_name, title
        from s_emp
        where dept_id in 
                (select id
                from s_dept
                where name='Sales');        

使用exists
select last_name,title
       from s_emp e
       where  exists
       (select 'x' --把查询结果定为constant,提高效率
        from s_dept s where s.id=e.dept_id and s.name='Sales');
2.2 not exists的使用
        与exists 含义相反,也在子查询中使用,用于替代not in。其他一样。如查询不在销售部的员工姓名
select last_name,title
       from s_emp e
       where  not exists
       (select 'x' --把查询结果定为constant,提高效率
        from s_dept s where s.id=e.dept_id and s.name='Sales');
3.with子句
9i新增语法
1.使用with子句可以让子查询重用相同的with查询块,通过select调用,一般在with查询用到多次情况下。

2.with子句的返回结果存到用户的临时表空间中,只做一次查询,提高效率。

3.有多个查询的时候,第1个用with,后面的不用with,并且用逗号隔开。

5.最后一个with子句与下面的查询之间不能有逗号,只通过右括号分割,查询必须用括号括起来

6.如果定义了with子句,而在查询中不使用,那么会报ora-32035错误:未引用在with子句中定义的查询名。(至少一个with查询的name未被引用,解决方法是移除未被引用的with查询)

7.前面的with子句定义的查询在后面的with子句中可以使用。
With子句目的是为了重用查询。

语法:
With alias_name as (select1), --as和select中的括号都不能省略
alias_name2 as (select2),--后面的没有with,逗号分割
…
alias_namen as (select n) –与下面的查询之间没有逗号
Select ….
如查询销售部门员工的姓名:
  --with clause
with a as
     (select id from s_dept where name='Sales' order by id)
  select last_name,title
         from s_emp where dept_id in (select * from a);--使用select查询别名

使用with子句,可以在复杂的查询中预先定义好一个结果集,然后在查询中反复使用,不使用会报错。而且with子句获得的是一个临时表,如果在查询中使用,必须采用select  from with查询名,比如
With cnt as(select count(*) from table)
Select cnt+1 from dual;
是错误的。必须是
   With cnt as(select count(*) shumu from user_tables)
Select shumu+1 from cnt;
--直接引用with子查询中的列别名。

        一个with查询的实例:
        查询出部门的总薪水大于所有部门平均总薪水的部门。部门表s_dept,员工表s_emp。
分析:做这个查询,首先必须计算出所有部门的总薪水,然后计算出总薪水的平均薪水,再筛选出部门的总薪水大于所有部门总薪水平均薪水的部门。那么第1步with查询查出所有部门的总薪水,第2步用with从第1步获得的结果表中查询出平均薪水,最后利用这两次的with查询比较总薪水大于平均薪水的结果,如下:
with 
--step1:查询出部门名和部门的总薪水
dept_costs as(
            select a.name,sum(b.salary) dept_total
              from 
                      s_dept a,s_emp b
                     where a.id=b.dept_id
                     group by a.name
),
--step2:利用上一个with查询的结果,计算部门的平均总薪水
avg_costs as(
           select sum(dept_total)/count(*) dept_avg
            from dept_costs         
)
--step3:从两个with查询中比较并且输出查询结果
select name,dept_total
  from dept_costs
  where 
   dept_total>
    (
     select dept_avg
      from 
     avg_costs
    )
   order by name;

从上面的查询可以看出,前面的with查询的结果可以被后面的with查询重用,并且对with查询的结果列支持别名的使用,在最终查询中必须要引用所有with查询,否则会报错ora-32035错误。



再如有这样一个需求:一个查询,如果查询的结果行不满足是10的倍数,则补空行,直到是查询出的行数是10的倍数。例如:select * from trademark这个查询。
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查询比10的倍数差几个空行
select id,name
  from trademark
union all        --空行加进去
select null,null  --补空行
from dual connect by rownum<=(select shumu from cnt); --10个中connect by可以使用子查询
10g之前的写法
with cnt as (select 10-mod(count(*),10) shumu from trademark) –查询比10的倍数差几个空行
select id,name
  from trademark
union all        --空行加进去
select null,null  --补空行
from all_objects where rownum<=(select shumu from cnt);--使用all_objects行比较多



4.merge into合并资料 
语法:(其中as可以省略)
MERGE INTO table_name AS table_alias
USING (table|view|sub_query) AS alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET
col1 = col_val1,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)—多个列以逗号分割                      //可以不指定列
VALUES (column_values);

作用:将源数据(来源于实际的表,视图,子查询)更新或插入到指定的表中(必须实际存在),依赖于on条件,好处是避免了多个insert和update操作。Merge是一个目标性明确的操作符,不允许在一个merge语句中对相同的行insert或update操作。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。例子如下:

drop table t;
CREATE TABLE T AS SELECT ROWNUM ID, A.* from DBA_OBJECTS A;

drop table t1;
CREATE TABLE T1 AS 
SELECT ROWNUM ID, OWNER, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE
from DBA_TABLES;


select *  from dba_objects;
select *  from dba_tables;

MERGE INTO T1 USING T 
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--insert后面不写表示插入全部列


MERGE INTO T1 USING T 
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME, T.OBJECT_TYPE);--常见错误,连接条件不能获得稳定的行,可以使用下面的用子查询


MERGE INTO T1 
USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID from T GROUP BY OWNER, OBJECT_NAME) T 
ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
  WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);


SELECT ID, OWNER, OBJECT_NAME, OBJECT_TYPE from T
MINUS
SELECT * from T1;

drop table subs;
create table subs(msid number(9),
                    ms_type char(1),
                  areacode number(3)
                    );
                    
     drop table acct;               
                     create table acct(msid number(9),
                     bill_month number(6),
                    areacode   number(3),
                    fee        number(8,2) default 0.00);
                    
insert into subs values(905310001,0,531);
insert into subs values(905320001,1,532);
insert into subs values(905330001,2,533);                 
commit;

merge into acct a --操作的表
      using subs b on (a.msid=b.msid)--使用原始数据来源的表,并且制定条件,条件必须有括号
     when matched then
          update set a.areacode=b.areacode--当匹配的时候,执行update操作,和直接update的语法不一样,不需要制定表名
     when not matched then--当不匹配的时候,执行insert操作,也不需要制定表名,若指定字段插入,则在insert后用括号标明,不指定是全部插入
          insert(msid,bill_month,areacode) values(b.msid,'200702',b.areacode);
          
   
    
另外,MERGE语句的UPDATE不能修改用于连接的列,否则会报错
select *  from acct;
select * from subs;
--10g新特性,单个操作
merge into acct a
      using subs b on(a.msid=b.msid)
    when not matched then--只有单个not matched的时候,只做插入,不做更新,只有单个matched的时候,只做更新操作
         insert(a.msid,a.bill_month,a.areacode) values(b.msid,'200702',b.areacode);
         
update acct set areacode=800 where msid=905320001;

delete from acct where areacode=533 or areacode=531;

insert into acct values(905320001,'200702',800,0.00);


--删除重复行
delete from subs b where b.rowid<(
select max(a.rowid) from subs a where a.msid=b.msid and a.ms_type=b.ms_type and a.areacode=b.areacode);

--10g新特性,merge操作之后,只有匹配的update操作才可以,用delete where子句删除目标表中满足条件的行。
  merge into acct a 
     using subs b on (a.msid=b.msid)
   when MATCHED then
        update set a.areacode=b.areacode        
        delete where (b.ms_type!=0)
        when NOT MATCHED then
        insert(msid,bill_month,areacode) 
        values(b.msid,'200702',b.areacode)
        where b.ms_type=0;
  --10g新特性,满足条件的插入和更新          
merge into acct a 
     using subs b on (a.msid=b.msid)     
   when MATCHED then
        update set a.areacode=b.areacode
        where b.ms_type=0
   when NOT MATCHED then
        insert(msid,bill_month,areacode) 
        values(b.msid,'200702',b.areacode)
        where b.ms_type=0;

select *  from subs where ms_type=0;
posted @ 2011-08-22 14:28 hinsxun 阅读(511) 评论(0) 编辑

使用RegularExpressionValidator验证
文章分类:Web前端 
使用RegularExpressionValidator验证:

只能输入数字:“^[0-9]*$”
只能输入n位的数字:“^d{n}$”
只能输入至少n位数字:“^d{n,}$”
只能输入m-n位的数字:“^d{m,n}$”
只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$”
只能输入有两位小数的正实数:“^[0-9]+(.[0-9]{2})?$”
只能输入有1-3位小数的正实数:“^[0-9]+(.[0-9]{1,3})?$”
只能输入非零的正整数:“^+?[1-9][0-9]*$”
只能输入非零的负整数:“^-[1-9][0-9]*$”
只能输入长度为3的字符:“^.{3}$”
只能输入由26个英文字母组成的字符串:“^[A-Za-z]+$”
只能输入由26个大写英文字母组成的字符串:“^[A-Z]+$”
只能输入由26个小写英文字母组成的字符串:“^[a-z]+$”
只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+$”
只能输入由数字、26个英文字母或者下划线组成的字符串:“^w+$”
验证用户密码:“^[a-zA-Z]w{5,17}$”正确格式为:以字母开头,长度在6-18之间,

只能包含字符、数字和下划线。
验证是否含有^%&',;=?$"等字符:“[^%&',;=?$x22]+”
只能输入汉字:“^[u4e00-u9fa5],{0,}$”
验证Email地址:"^[^@]([a-zA-Z_0-9.])+@([a-zA-Z_0-9.])+[^@]$"
验证InternetURL:“^http://([w-]+.)+[w-]+(/[w-./?%&=]*)?$”

验证电话号码:“^((d{3,4})|d{3,4}-)?d{7,8}$”

asp.net里面自带的验证Email地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

只能输入数字与符号“-”     ^[\d\-]+$

只能输入数字、英文、下划线、中杠线      [\w\-]+

posted @ 2011-06-17 11:32 hinsxun 阅读(66) 评论(0) 编辑
 SELECT TableName =D.NAME,
       TableComment = CASE
         WHEN A.COLORDER = 1 THEN
          ISNULL(F.VALUE, ' ')
         ELSE
          ' '
       END,
       ColumnIndex = A.COLORDER,
       ColumnName = A.NAME,
       ColumnIdentity = CASE
         WHEN COLUMNPROPERTY(A.ID, A.NAME, 'ISIDENTITY ') = 1 THEN
          '1 '
         ELSE
          '0'
       END,
       PrimaryKey = CASE
         WHEN EXISTS
          (SELECT 1
                 FROM SYSOBJECTS
                WHERE XTYPE = 'PK '
                  AND PARENT_OBJ = A.ID
                  AND NAME IN
                      (SELECT NAME
                         FROM SYSINDEXES
                        WHERE INDID IN (SELECT INDID
                                          FROM SYSINDEXKEYS
                                         WHERE ID = A.ID
                                           AND COLID = A.COLID))) THEN
          '1'
         ELSE
          '0'
       END,
       ColumnType = B.NAME,
       ColumnBit = A.LENGTH,
       ColumnLength = COLUMNPROPERTY(A.ID, A.NAME, 'PRECISION '),
       ColumnDecimal = ISNULL(COLUMNPROPERTY(A.ID, A.NAME, 'SCALE '), 0),
       ColumnNullAble = CASE
         WHEN A.ISNULLABLE = 1 THEN
          '1'
         ELSE
          '0'
       END,
       DefaultValue = ISNULL(E.TEXT, ' '),
       ColumnComment = ISNULL(G. VALUE, ' ')
  FROM SYSCOLUMNS A
  LEFT JOIN SYSTYPES B ON A.XUSERTYPE = B.XUSERTYPE
 INNER JOIN SYSOBJECTS D ON A.ID = D.ID
                        AND D.XTYPE = 'U '
                        AND D.NAME <> 'DTPROPERTIES '
  LEFT JOIN SYSCOMMENTS E ON A.CDEFAULT = E.ID
  LEFT JOIN sys.extended_properties G ON A.ID = G.major_id
                                     AND A.COLID = G.minor_id
  LEFT JOIN sys.extended_properties F ON D.ID = F.major_id
                                     AND F.minor_id = 0
 WHERE D.NAME ='TABLE_NAME' 
 ORDER BY A.ID, A.COLORDER
posted @ 2011-05-11 15:54 hinsxun 阅读(21) 评论(0) 编辑
SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。
nbsp;   ; IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
     @@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
     SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
     例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。
     假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。
     @@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。
     SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。
而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。
====================================================================================
也许大家对SQL Server中的 @@IDENTITY 都不陌生,都知道它是获取数据表中最后一条插入数据的IDENTITY值。
比如,表 A 中有个 ID 为自增1的字段,假设此时 ID 的值为100,现在如果我往表A插入一条数据,并在插入后 
SELECT @@IDENTITY,则其返回 101,最后一条IDENTITY域(即ID域)的值。

现在问题来了,为什么说要慎用@@IDENTITY呢?原因是 @@IDENTITY 它总是获取最后一条变更数据的自增字段的值,
而忽略了进行变更操作所在的范围约束。比如,我有表 A 和表 B 两个表,现在我在表 A 上定义了一个Insert触发器,
当在表 A 中插入一条数据时,自动在表 B 也插入一条数据。此时,大家注意,有两个原子操作:在A中插入一条数据, 接着在B中随后插入一条数据。

现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,使用了 
SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢? 答案很明显,是谁最后插入就输出谁,
那么就是 B 了。于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还
会影响到整个系统数据的混乱。

因此,对于这种情况,建议大家慎用 @@IDENTITY,而尽量采用 SCOPE_IDENTITY() 函数替换之。SCOPE_IDENTITY() 
也是得到最后一条自增域的值,但是它是仅限在一个操作范围之内,而不像 @@IDENTITY 是取全局操作的最后一步操作
所产生的自增域的值的。
也许大家对SQL Server中的 @@IDENTITY 都不陌生,都知道它是获取数据表中最后一条插入数据的IDENTITY值。
比如,表 A 中有个 ID 为自增1的字段,假设此时 ID 的值为100,现在如果我往表A插入一条数据,并在插入后 
SELECT @@IDENTITY,则其返回 101,最后一条IDENTITY域(即ID域)的值。

现在问题来了,为什么说要慎用@@IDENTITY呢?原因是 @@IDENTITY 它总是获取最后一条变更数据的自增字段的值,
而忽略了进行变更操作所在的范围约束。比如,我有表 A 和表 B 两个表,现在我在表 A 上定义了一个Insert触发器,
当在表 A 中插入一条数据时,自动在表 B 也插入一条数据。此时,大家注意,有两个原子操作:在A中插入一条数据, 接着在B中随后插入一条数据。

现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,使用了 
SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢? 答案很明显,是谁最后插入就输出谁,
那么就是 B 了。于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还
会影响到整个系统数据的混乱。

因此,对于这种情况,建议大家慎用 @@IDENTITY,而尽量采用 SCOPE_IDENTITY() 函数替换之。SCOPE_IDENTITY() 
也是得到最后一条自增域的值,但是它是仅限在一个操作范围之内,而不像 @@IDENTITY 是取全局操作的最后一步操作
所产生的自增域的值的。
也许大家对SQL Server中的 @@IDENTITY 都不陌生,都知道它是获取数据表中最后一条插入数据的IDENTITY值。
比如,表 A 中有个 ID 为自增1的字段,假设此时 ID 的值为100,现在如果我往表A插入一条数据,并在插入后 
SELECT @@IDENTITY,则其返回 101,最后一条IDENTITY域(即ID域)的值。

现在问题来了,为什么说要慎用@@IDENTITY呢?原因是 @@IDENTITY 它总是获取最后一条变更数据的自增字段的值,
而忽略了进行变更操作所在的范围约束。比如,我有表 A 和表 B 两个表,现在我在表 A 上定义了一个Insert触发器,
当在表 A 中插入一条数据时,自动在表 B 也插入一条数据。此时,大家注意,有两个原子操作:在A中插入一条数据, 接着在B中随后插入一条数据。

现在我们想下,假设上面表 A 和表 B 都有IDENTITY自增域,那么我们在表 A 插入一条数据后,使用了 
SELECT @@IDENTITY 输出时,输出的到底是 A 还是 B 的自增域的值呢? 答案很明显,是谁最后插入就输出谁,
那么就是 B 了。于是,我本意是想得到 A 的自增域值,结果得到了 B 的自增域值,一只 BUG 随之诞生,搞不好还
会影响到整个系统数据的混乱。

因此,对于这种情况,建议大家慎用 @@IDENTITY,而尽量采用 SCOPE_IDENTITY() 函数替换之。SCOPE_IDENTITY() 
也是得到最后一条自增域的值,但是它是仅限在一个操作范围之内,而不像 @@IDENTITY 是取全局操作的最后一步操作
所产生的自增域的值的。
=============================================================================

预知法

预知法,其实相对简单一些,我们可以设置一个主键,但该主键不设置为自增,因为在插入前,我们自己通过程序的方法获得一个唯一的值作为我们的主键. 这样就避免了我们插入后不能获得主键的缺点,并且由于我们是预知我们要插入的值,所以在插入后,我们就可以不通过数据库提供的方法,再次获得主键.

在这里我推荐使用一种比较好的预知序列,这就是GUID.大家都知道任何两台计算机都不可能产生一样的GUID值,并且在一台机器上产生的GUID也不会重复.

我们在插入数据库前,自己通过GUID函数获得一个可用的GUID,然后用它做为主键来插入到数据库中.

但是这也有一个缺点:GUID一般都比较长16位,并且它不具有任何的含义,这样在大批量插入时有一定的性能影响.

后知法

后知法是本次我介绍的比较实用的方法,通过SQL Server的两个函数和一个系统变量获得当前最新的主键值

两个函数分别是:

IDENT_CURRENT

SCOPE_IDENTITY

系统变量值为:

@@IDENTITY

其中IDENT_CURRENT和SCOPE_IDENTITY的主要区别在于,SCOPE_IDENTITY主要用在一个会话中,只对当前会话插入的表的最后的IDENTITY,而IDENT_CURRENT没有作用域的概念,它用于特定的表.

其中我主要介绍一下系统变量@@IDENTITY,以下是SQL Server在线帮助提供的信息

@@IDENTITY
新增信息 - 2001 年 9 月

返回最后插入的标识值。

语法
@@IDENTITY

返回类型
numeric

注释
在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。如 果触发器在具有标识列的表上执行插入操作后激发,并且触发器插入到另一个没有标识列的表中,则 @@IDENTITY 将返回第一个插入的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。

在返回插入到表的 @@IDENTITY 列的最后一个值方面,@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 函数类似。

@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。

IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。

@@IDENTITY 函数的作用域是执行该函数的本地服务器。此函数不能应用于远程或链接服务器。要获得其他服务器上的标识值,请在远程服务器或链接服务器上执行存储过程,并使该存储过程(在远程或链接服务器的环境中执行)收集标识值并将其返回本地服务器上的调用连接。

示例
下面的示例向带有标识列的表中插入一行,并用 @@IDENTITY 显示在新行中使用的标识值。

INSERT INTO jobs (job_desc,min_lvl,max_lvl)
VALUES ('Accountant',12,125)
SELECT @@IDENTITY AS 'Identity'

具体实现的方法是,写一个存储过程,并且在插入完成以后,返回@@IDENTITY,以下是一个存储过程的例子:

下列示例将创建两个表 TZ 和 TY,并在 TZ 上创建一个 INSERT 触发器。当将某行插入表 TZ 中时,触发器 (Ztrig) 将激发并在 TY 中插入一行。

USE tempdb
GO
CREATE TABLE TZ (
   Z_id int IDENTITY(1,1)PRIMARY KEY,
   Z_name varchar(20) NOT NULL)

INSERT TZ
   VALUES ('Lisa')
INSERT TZ
   VALUES ('Mike')
INSERT TZ
   VALUES ('Carla')

SELECT * FROM TZ

--Result set: This is how table TZ looks
Z_id   Z_name
-------------
1      Lisa
2      Mike
3      Carla

CREATE TABLE TY (
   Y_id int IDENTITY(100,5)PRIMARY KEY,
   Y_name varchar(20) NULL)

INSERT TY (Y_name)
   VALUES ('boathouse')
INSERT TY (Y_name)
   VALUES ('rocks')
INSERT TY (Y_name)
   VALUES ('elevator')

SELECT * FROM TY
--Result set: This is how TY looks:
Y_id Y_name
---------------
100   boathouse
105   rocks
110   elevator

/*Create the trigger that inserts a row in table TY 
when a row is inserted in table TZ*/
CREATE TRIGGER Ztrig
ON TZ
FOR INSERT AS 
   BEGIN
   INSERT TY VALUES ('')
   END

/*FIRE the trigger and find out what identity values you get 
with the @@IDENTITY and SCOPE_IDENTITY functions*/
INSERT TZ VALUES ('Rosalie')

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT   @@IDENTITY AS [@@IDENTITY]
GO

--Here is the result set.
SCOPE_IDENTITY
4
/*SCOPE_IDENTITY returned the last identity value in the same scope, which was the insert on table TZ*/

@@IDENTITY
115
/*@@IDENTITY returned the last identity value inserted to TY by the trigger, which fired due to an earlier


值得注意的是SCOPE_IDENTITY返回的本过程中影响的表TZ,而触法器影响的TY表不被反映,而@@IDENTITY则反映当前所有影响的表,即包含触发器影响的TY表

在使用过程中我们可以使用RETURN @@identity返回一个存储过程获得的值,然后在程序中获得这个值,这样就能获得当前插入后生成的主键.

posted @ 2011-02-15 14:29 hinsxun 阅读(147) 评论(0) 编辑

SELECT o.name AS "Table Name", i.rowcnt AS "Row Count"
FROM sysobjects o, sysindexes i
WHERE i.id = o.id
AND i.indid IN(0,1)
AND o.xtype = 'u' --只统计用户表
AND o.name <> 'sysdiagrams'
ORDER BY i.rowcnt DESC --按行排降序

COMPUTE SUM(i.rowcnt), count(o.name); --汇总行数,表数
GO

转自:http://www.cnblogs.com/rockniu/archive/2007/12/20/1006716.html

posted @ 2011-02-14 15:24 hinsxun 阅读(43) 评论(0) 编辑
摘要: Jquery代码$(&ldquo;input:[name=study]:radio:checked&rdquo;)这段代码取得的是所有name属性为&ldquo;study&rdquo;而且已经被选中的radio的jquery对象,通过判断他的length 是否等于0,就可以知道这个radio选项是否有一个被选中了。$(&ldquo;input[name=study]:text&rdquo;)这段代码取得的是name属性为&ldquo;study&rdquo;的text输入框的jquery对象。恩~~说的可能大家不太明白~~~呵呵阅读全文
posted @ 2011-02-13 16:33 hinsxun 阅读(1331) 评论(0) 编辑
摘要: 放到page中去处理 不管是服务器控件还是用户控件 都通用C#代码C# codeVB代码:VB.NET code阅读全文
posted @ 2011-01-26 17:08 hinsxun 阅读(25) 评论(0) 编辑