Sql常用語法


下列語句部分是Mssql語句,不可以在access中使用。

 

SQL分類:

DDL—數據定義語言(CREATEALTERDROPDECLARE)

DML—數據操縱語言(SELECTDELETEUPDATEINSERT)

DCL—數據控制語言(GRANTREVOKECOMMITROLLBACK) 首先,簡要介紹基礎語句:

1、說明:創建數據庫

CREATE DATABASE database-name

 

2、說明:刪除數據庫

drop database dbname

 

3、說明:備份sql server

--- 創建 備份數據的 device

USE master

EXEC sp_addumpdevice 'disk', 'testBack', 'c:mssql7backupMyNwind_1.dat'

--- 開始 備份

BACKUP DATABASE pubs TO testBack

 

4、說明:創建新表

create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)根據已有的表創建新表:

Acreate table tab_new like tab_old (使用舊表創建新表)

Bcreate table tab_new as select col1,col2 from tab_old definition only

 

5、說明:刪除新表drop table tabname

 

6、說明:增加一個列

 

Alter table tabname add column col type注:列增加后將不能刪除。DB2中列加上后數據類型也不能改變,唯一能改變的是增加varchar類型的長度。

 

7、說明:添加主鍵: Alter table tabname add primary key(col) 說明:刪除主鍵: Alter table tabname drop primary key(col)

 

8、說明:創建索引:create [unique] index idxname on tabname(col.) 刪除索引:drop index idxname注:索引是不可更改的,想更改必須刪除重新建。

 

9、說明:創建視圖:create view viewname as select statement 刪除視圖:drop view viewname

 

10、說明:幾個簡單的基本的sql語句選擇:select * from table1 where 范圍插入:insert into table1(field1,field2) s(1,2)刪除:delete from table1 where 范圍更新:update table1 set field1=1 where 范圍查找:select * from table1 where field1 like %1% ---like的語法很精妙,查資料!排序:select * from table1 order by field1,field2 [desc]總數:select count * as totalcount from table1求和:select sum(field1) as sum from table1平均:select avg(field1) as avg from table1最大:select max(field1) as max from table1最小:select min(field1) as min from table1

 

11、說明:幾個高級查詢運算詞

A UNION 運算符

UNION 運算符通過組合其他兩個結果表(例如 TABLE1 TABLE2)並消去表中任何重復行而派生出一個結果表。當 ALL UNION 一起使用時(即 UNION ALL),不消除重復行。兩種情況下,派生表的每一行不是來自 TABLE1 就是來自 TABLE2

B EXCEPT 運算符

EXCEPT 運算符通過包括所有在 TABLE1 中但不在 TABLE2 中的行並消除所有重復行而派生出一個結果表。當 ALL EXCEPT 一起使用時 (EXCEPT ALL),不消除重復行。

C INTERSECT 運算符

INTERSECT 運算符通過只包括 TABLE1 TABLE2 中都有的行並消除所有重復行而派生出一個結果表。當 ALL INTERSECT 一起使用時 (INTERSECT ALL),不消除重復行。 注:使用運算詞的幾個查詢結果行必須是一致的。

 

12、說明:使用外連接

Aleft outer join 左外連接(左連接):結果集幾包括連接表的匹配行,也包括左連接表的所有行。

SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

Bright outer join: 右外連接(右連接):結果集既包括連接表的匹配連接行,也包括右連接表的所有行。

Cfull outer join 全外連接:不僅包括符號連接表的匹配行,還包括兩個連接表中的所有記錄。

 

不錯的sql語句

1、說明:復制表(只復制結構,源表名:a 新表名:b) (Access可用)法一:select * into b from a where 1<>1法二:select top 0 * into b from a

 

2、說明:拷貝表(拷貝數據,源表名:a 目標表名:b) (Access可用)

insert into b(a, b, c) select d,e,f from b;

 

3、說明:跨數據庫之間表的拷貝(具體數據使用絕對路徑) (Access可用)

insert into b(a, b, c) select d,e,f from b in ‘具體數據庫’ where 條件例子:..from b in '"&Server.MapPath(".")&"data.mdb" &"' where..

 

4、說明:子查詢(表名1a 表名2b)

select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)

 

5、說明:顯示文章、提交人和最后回復時間

select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

 

6、說明:外連接查詢(表名1a 表名2b)

select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

 

7、說明:在線視圖查詢(表名1a )

select * from (SELECT a,b,c FROM a) T where t.a > 1;

 

8、說明:between的用法,between限制查詢數據范圍時包括了邊界值,not between不包括

select * from table1 where time between time1 and time2

select a,b,c, from table1 where a not between 數值1 and 數值2

 

9、說明:in 的使用方法

select * from table1 where a [not] in (‘值1,’值2,’值4,’值6)

 

10、說明:兩張關聯表,刪除主表中已經在副表中沒有的信息

delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

 

11、說明:四表聯查問題:

select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

 

12、說明:日程安排提前五分鍾提醒

SQL: select * from 日程安排 where datediff('minute',f開始時間,getdate())>5

 

13、說明:一條sql 語句搞定數據庫分頁

select top 10 b.* from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主鍵字段 = a.主鍵字段 order by a.排序字段

 

14、說明:前10條記錄

select top 10 * form table1 where 范圍

 

15、說明:選擇在每一組b值相同的數據中對應的a最大的記錄的所有信息(類似這樣的用法可以用於論壇每月排行榜,每月熱銷產品分析,按科目成績排名,等等.)

select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

 

16、說明:包括所有在 TableA 中但不在 TableBTableC 中的行並消除所有重復行而派生出一個結果表

(select a from tableA ) except (select a from tableB) except (select a from tableC)

 

17、說明:隨機取出10條數據

select top 10 * from tablename order by newid()

 

18、說明:隨機選擇記錄

select newid()

 

19、說明:刪除重復記錄

Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

 

20、說明:列出數據庫里所有的表名

select name from sysobjects where type='U'

 

21、說明:列出表里的所有的

select name from syscolumns where id=object_id('TableName')

 

22、說明:列示typevenderpcs字段,以type字段排列,case可以方便地實現多重選擇,類似select 中的case

select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type顯示結果:

type vender pcs電腦 A 1電腦 A 1光盤 B 2光盤 A 2手機 B 3手機 C 3

 

23、說明:初始化表table1

TRUNCATE TABLE table1

 

24、說明:選擇從1015的記錄

select top 5 * from (select top 15 * from table order by id asc) table_別名 order by id desc

 

 

sql技巧

如何刪除一個表中重復的記錄?

create table a_dist(id int,name varchar(20))

 

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

 

exec up_distinct 'a_dist','id'

 

select * from a_dist

 

create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))

--f_key表示是分組字段﹐即主鍵字段

as

begin

declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer

select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) > 1'

exec(@sql)

open cur_rows

fetch cur_rows into @id,@max

while @@fetch_status=0

begin

select @max = @max -1

set rowcount @max

select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key

if @type=56

select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id

if @type=167

select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''''+ @id +''''

exec(@sql)

fetch cur_rows into @id,@max

end

close cur_rows

deallocate cur_rows

set rowcount 0

end

 

select * from systypes

select * from syscolumns where id = object_id('a_dist')

 

查詢數據的最大排序問題(只能用一條語句寫)

CREATE TABLE hard (qu char (11) ,co char (11) ,je numeric(3, 0))

 

insert into hard values ('A','1',3)

insert into hard values ('A','2',4)

insert into hard values ('A','4',2)

insert into hard values ('A','6',9)

insert into hard values ('B','1',4)

insert into hard values ('B','2',5)

insert into hard values ('B','3',6)

insert into hard values ('C','3',4)

insert into hard values ('C','6',7)

insert into hard values ('C','2',3)

 

 

要求查詢出來的結果如下:

 

qu co je

----------- ----------- -----

A 6 9

A 2 4

B 3 6

B 2 5

C 6 7

C 3 4

 

 

就是要按qu分組,每組中取je最大的前2位!!

而且只能用一句sql語句!!!

select * from hard a where je  in (select top 2 je from hard b where a.qu=b.qu order by je)

 

求刪除重復記錄的sql語句?

怎樣把具有相同字段的紀錄刪除,只留下一條。

例如,表test里有id,name字段

如果有name相同的記錄 只留下一條,其余的刪除。

name的內容不定,相同的記錄數不定。

有沒有這樣的sql語句?

==============================

A:一個完整的解決方案:

 

將重復的記錄記入temp1:

select [標志字段id],count(*) into temp1 from [表名]

group by [標志字段id]

having count(*)>1

 

2、將不重復的記錄記入temp1:

insert temp1 select [標志字段id],count(*) from [表名] group by [標志字段id] having count(*)=1

 

3、作一個包含所有不重復記錄的表:

select * into temp2 from [表名] where 標志字段id in(select 標志字段id from temp1)

 

4、刪除重復表:

delete [表名]

 

5、恢復表:

insert [表名] select * from temp2

 

6、刪除臨時表:

drop table temp1

drop table temp2

================================

B:

create table a_dist(id int,name varchar(20))

 

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

insert into a_dist values(1,'abc')

 

exec up_distinct 'a_dist','id'

 

select * from a_dist

 

create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))

--f_key表示是分組字段﹐即主鍵字段

as

begin

declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer

select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) > 1'

exec(@sql)

open cur_rows

fetch cur_rows into @id,@max

while @@fetch_status=0

begin

select @max = @max -1

set rowcount @max

select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key

if @type=56

select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id

if @type=167

select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''''+ @id +''''

exec(@sql)

fetch cur_rows into @id,@max

end

close cur_rows

deallocate cur_rows

set rowcount 0

end

 

select * from systypes

select * from syscolumns where id = object_id('a_dist')

 

行列轉換--普通

 

假設有張學生成績表(CJ)如下

Name Subject Result

張三 語文 80

張三 數學 90

張三 物理 85

李四 語文 85

李四 數學 92

李四 物理 82

 

想變成

姓名 語文 數學 物理

張三 80 90 85

李四 85 92 82

 

declare @sql varchar(4000)

set @sql = 'select Name'

select @sql = @sql + ',sum(case Subject when '''+Subject+''' then Result end) ['+Subject+']'

from (select distinct Subject from CJ) as a

select @sql = @sql+' from test group by name'

exec(@sql)

 

行列轉換--合並

 

有表A,

id pid

1 1

1 2

1 3

2 1

2 2

3 1

如何化成表B:

id pid

1 1,2,3

2 1,2

3 1

 

創建一個合並的函數

create function fmerg(@id int)

returns varchar(8000)

as

begin

declare @str varchar(8000)

set @str=''

select @str=@str+','+cast(pid as varchar) from A where id=@id

set @str=right(@str,len(@str)-1)

return(@str)

End

go

 

--調用自定義函數得到結果

select distinct id,dbo.fmerg(id) from A

 

 

如何取得一個數據表的所有列名

 

方法如下:先從SYSTEMOBJECT系統表中取得數據表的SYSTEMID,然后再SYSCOLUMN表中取得該數據表的所有列名。

SQL語句如下:

declare @objid int,@objname char(40)

set @objname = 'tablename'

select @objid = id from sysobjects where id = object_id(@objname)

select 'Column_name' = name from syscolumns where id = @objid order by colid

 

 

SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='users'

通過SQL語句來更改用戶的密碼

 

修改別人的,需要sysadmin role

EXEC sp_password NULL, 'newpassword', 'User'

 

如果帳號為SA執行EXEC sp_password NULL, 'newpassword', sa

 

怎么判斷出一個表的哪些字段不允許為空?

 

select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE='NO' and TABLE_NAME=tablename

如何在數據庫里找到含有相同字段的表?

a. 查已知列名的情況

SELECT b.name as TableName,a.name as columnname

From syscolumns a INNER JOIN sysobjects b

ON a.id=b.id

AND b.type='U'

AND a.name='你的字段名字'

未知列名查所有在不同表出現過的列名

Select o.name As tablename,s1.name As columnname

From syscolumns s1, sysobjects o

Where s1.id = o.id

And o.type = 'U'

And Exists (

Select 1 From syscolumns s2

Where s1.name = s2.name

And s1.id <> s2.id

)

查詢第xxx行數據

 

假設id是主鍵:

select * from (select top xxx * from yourtable) aa where not exists(select 1 from (select top xxx-1 * from yourtable) bb where aa.id=bb.id)

 

如果使用游標也是可以的

fetch absolute [number] from [cursor_name]

行數為絕對行數

 

SQL Server日期計算

a. 一個月的第一天

SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)

b. 本周的星期一

SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)

c. 一年的第一天

SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)

d. 季度的第一天

SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)

e. 上個月的最后一天

SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))

f. 去年的最后一天

SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))

g. 本月的最后一天

SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))

h. 本月的第一個星期一

select DATEADD(wk, DATEDIFF(wk,0,

dateadd(dd,6-datepart(day,getdate()),getdate())

), 0)

i. 本年的最后一天

SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))

獲取表結構[ 'sysobjects' 替換 'tablename' 即可]

 

SELECT CASE IsNull(I.name, '')

When '' Then ''

Else '*'

End as IsPK,

Object_Name(A.id) as t_name,

A.name as c_name,

IsNull(SubString(M.text, 1, 254), '') as pbc_init,

T.name as F_DataType,

CASE IsNull(TYPEPROPERTY(T.name, 'Scale'), '')

WHEN '' Then Cast(A.prec as varchar)

ELSE Cast(A.prec as varchar) + ',' + Cast(A.scale as varchar)

END as F_Scale,

A.isnullable as F_isNullAble

FROM Syscolumns as A

JOIN Systypes as T

ON (A.xType = T.xUserType AND A.Id = Object_id('sysobjects') )

LEFT JOIN ( SysIndexes as I

JOIN Syscolumns as A1

ON ( I.id = A1.id and A1.id = object_id('sysobjects') and (I.status & 0x800) = 0x800 AND A1.colid <= I.keycnt) )

ON ( A.id = I.id AND A.name = index_col('sysobjects', I.indid, A1.colid) )

LEFT JOIN SysComments as M

ON ( M.id = A.cdefault and ObjectProperty(A.cdefault, 'IsConstraint') = 1 )

ORDER BY A.Colid ASC

 

 

提取數據庫內所有表的字段詳細說明的SQL語句

 

SELECT

(case when a.colorder=1 then d.name else '' end) N'表名',

a.colorder N'字段序號',

a.name N'字段名',

(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then ''else ''

end) N'標識',

(case when (SELECT count(*)

FROM sysobjects

WHERE (name in

(SELECT name

FROM sysindexes

WHERE (id = a.id) AND (indid in

(SELECT indid

FROM sysindexkeys

WHERE (id = a.id) AND (colid in

(SELECT colid

FROM syscolumns

WHERE (id = a.id) AND (name = a.name))))))) AND

(xtype = 'PK'))>0 then '' else '' end) N'主鍵',

b.name N'類型',

a.length N'占用字節數',

COLUMNPROPERTY(a.id,a.name,'PRECISION') as N'長度',

isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as N'小數位數',

(case when a.isnullable=1 then ''else '' end) N'允許空',

isnull(e.text,'') N'默認值',

isnull(g.[value],'') AS N'字段說明'

FROM syscolumns a

left join systypes b

on a.xtype=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 sysproperties g

on a.id=g.id AND a.colid = g.smallid

order by object_name(a.id),a.colorder

 

快速獲取表test的記錄總數[對大容量表非常有效]

 

快速獲取表test的記錄總數:

select rows from sysindexes where id = object_id('test') and indid in (0,1)

 

update 2 set KHXH=(ID+1)\2 2行遞增編號

update [23] set id1 = 'No.'+right('00000000'+id,6) where id not like 'No%' //遞增

update [23] set id1= 'No.'+right('00000000'+replace(id1,'No.',''),6) //補位遞增

delete from [1] where (id%2)=1

奇數

替換表名字段

update [1] set domurl = replace(domurl,'Upload/Imgswf/','Upload/Photo/') where domurl like '%Upload/Imgswf/%'

截位

SELECT LEFT(表名, 5)

 

截位

SELECT LEFT(表名, 5)

MS SQL ServerSQL語句導入導出大全

/*******   導出到excel

EXEC master..xp_cmdshell 'bcp SettleDB.dbo.shanghu out c:\temp1.xls -c -q -S"GNETDATA/GNETDATA" -U"sa" -P""'

 

/***********   導入Excel

SELECT *

FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',

   'Data Source="c:\test.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...xactions

 

 

SELECT cast(cast(科目編號 as numeric(10,2)) as nvarchar(255))+' ' 轉換后的別名

FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',

   'Data Source="c:\test.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...xactions

 

select    *    from OPENROWSET('MICROSOFT.JET.OLEDB.4.0','Excel 5.0;HDR=YES;DATABASE=c:\Book1.xls',Sheet1$)

 

HDR=YES;Excel第一行當成標題行

 

HDR=NO;第一行不當成標題行

 

 

/** 導入文本文件

EXEC master..xp_cmdshell 'bcp "dbname..tablename" in c:\DT.txt -c -Sservername -Usa -Ppassword'

 

/** 導出文本文件

EXEC master..xp_cmdshell 'bcp "dbname..tablename" out c:\DT.txt -c -Sservername -Usa -Ppassword'

EXEC master..xp_cmdshell 'bcp "Select * from dbname..tablename" queryout c:\DT.txt -c -Sservername -Usa -Ppassword'

 

導出到TXT文本,用逗號分開

exec master..xp_cmdshell 'bcp "庫名..表名" out "d:\tt.txt" -c -t ,-U sa -P password'

 

 

BULK INSERT 庫名..表名

FROM 'c:\test.txt'

WITH (

     FIELDTERMINATOR = ';',

     ROWTERMINATOR = '\n'

)

 

 

--/* dBase IV文件

select * from

OPENROWSET('MICROSOFT.JET.OLEDB.4.0'

,'dBase IV;HDR=NO;IMEX=2;DATABASE=C:\','select * from [客戶資料4.dbf]')

--*/

 

--/* dBase III文件

select * from

OPENROWSET('MICROSOFT.JET.OLEDB.4.0'

,'dBase III;HDR=NO;IMEX=2;DATABASE=C:\','select * from [客戶資料3.dbf]')

--*/

 

--/* FoxPro 數據庫

select * from openrowset('MSDASQL',

'Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\',

'select * from [aa.DBF]')

--*/

 

/**************導入DBF文件****************/

select * from openrowset('MSDASQL',

'Driver=Microsoft Visual FoxPro Driver;

SourceDB=e:\VFP98\data;

SourceType=DBF',

'select * from customer where country != "USA" order by country')

go

/***************** 導出到DBF ***************/

如果要導出數據到已經生成結構(即現存的)FOXPRO表中,可以直接用下面的SQL語句

 

insert into openrowset('MSDASQL',

'Driver=Microsoft Visual FoxPro Driver;SourceType=DBF;SourceDB=c:\',

'select * from [aa.DBF]')

select * from

 

說明:

SourceDB=c:\   指定foxpro表所在的文件夾

aa.DBF         指定foxpro表的文件名.

 

 

/*************導出到Access********************/

insert into openrowset('Microsoft.Jet.OLEDB.4.0',

    'x:\A.mdb';'admin';'',A) select * from 數據庫名..B

 

/*************導入Access********************/

insert into B selet * from openrowset('Microsoft.Jet.OLEDB.4.0',

    'x:\A.mdb';'admin';'',A)

 

*********************   導入 xml 文件

 

DECLARE @idoc int

DECLARE @doc varchar(1000)

--sample XML document

SET @doc ='

<root>

   <Customer cid= "C1" name="Janine" city="Issaquah">

       <Order oid="O1" date="1/20/1996" amount="3.5" />

       <Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied

       </Order>

    </Customer>

    <Customer cid="C2" name="Ursula" city="Oelde" >

       <Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue

              white red">

             <Urgency>Important</Urgency>

             Happy Customer.

       </Order>

       <Order oid="O4" date="1/20/1996" amount="10000"/>

    </Customer>

</root>

'

-- Create an internal representation of the XML document.

EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

 

-- Execute a SELECT statement using OPENXML rowset provider.

SELECT *

FROM OPENXML (@idoc, '/root/Customer/Order', 1)

       WITH (oid      char(5),

             amount   float,

             comment ntext 'text()')

EXEC sp_xml_removedocument @idoc

 

 

/********************導整個數據庫*********************************************/

 

bcp實現的存儲過程

 

 

/*

實現數據導入/導出的存儲過程

          根據不同的參數,可以實現導入/導出整個數據庫/單個表

調用示例:

--導出調用示例

----導出單個表

exec file2table 'zj','','','xzkh_sa..地區資料','c:\zj.txt',1

----導出整個數據庫

exec file2table 'zj','','','xzkh_sa','C:\docman',1

 

--導入調用示例

----導入單個表

exec file2table 'zj','','','xzkh_sa..地區資料','c:\zj.txt',0

----導入整個數據庫

exec file2table 'zj','','','xzkh_sa','C:\docman',0

 

*/

if exists(select 1 from sysobjects where name='File2Table' and objectproperty(id,'IsProcedure')=1)

drop procedure File2Table

go

create procedure File2Table

@servername varchar(200)   --服務器名

,@username varchar(200)    --用戶名,如果用NT驗證方式,則為空''

,@password varchar(200)    --密碼

,@tbname varchar(500)    --數據庫.dbo.表名,如果不指定:.dbo.表名,則導出數據庫的所有用戶表

,@filename varchar(1000)   --導入/導出路徑/文件名,如果@tbname參數指明是導出整個數據庫,則這個參數是文件存放路徑,文件名自動用表名.txt

,@isout bit       --1為導出,0為導入

as

declare @sql varchar(8000)

 

if @tbname like '%.%.%' --如果指定了表名,則直接導出單個表

begin

set @sql='bcp '+@tbname

   +case when @isout=1 then ' out ' else ' in ' end

   +' "'+@filename+'" /w'

   +' /S '+@servername

   +case when isnull(@username,'')='' then '' else ' /U '+@username end

   +' /P '+isnull(@password,'')

exec master..xp_cmdshell @sql

end

else

begin --導出整個數據庫,定義游標,取出所有的用戶表

declare @m_tbname varchar(250)

if right(@filename,1)<>'\' set @filename=@filename+'\'

 

set @m_tbname='declare #tb cursor for select name from '+@tbname+'..sysobjects where xtype=''U'''

exec(@m_tbname)

open #tb

fetch next from #tb into @m_tbname

while @@fetch_status=0

begin

   set @sql='bcp '+@tbname+'..'+@m_tbname

    +case when @isout=1 then ' out ' else ' in ' end

    +' "'+@filename+@m_tbname+'.txt " /w'

    +' /S '+@servername

    +case when isnull(@username,'')='' then '' else ' /U '+@username end

    +' /P '+isnull(@password,'')

   exec master..xp_cmdshell @sql

   fetch next from #tb into @m_tbname

end

close #tb

deallocate #tb

end

go

 

 

/**********************Excel導到Txt****************************************/

想用

select * into opendatasource(...) from opendatasource(...)

實現將一個Excel文件內容導入到一個文本文件

 

假設Excel中有兩列,第一列為姓名,第二列為很行帳號(16)

且銀行帳號導出到文本文件后分兩部分,前8位和后8位分開。

 

 

如果要用你上面的語句插入的話,文本文件必須存在,而且有一行:姓名,銀行賬號1,銀行賬號2

然后就可以用下面的語句進行插入

注意文件名和目錄根據你的實際情況進行修改.

 

insert into

opendatasource('MICROSOFT.JET.OLEDB.4.0'

,'Text;HDR=Yes;DATABASE=C:\'

)...[aa#txt]

--,aa#txt)

--*/

select 姓名,銀行賬號1=left(銀行賬號,8),銀行賬號2=right(銀行賬號,8)

from

opendatasource('MICROSOFT.JET.OLEDB.4.0'

,'Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls'

--,Sheet1$)

)...[Sheet1$]

 

如果你想直接插入並生成文本文件,就要用bcp

 

declare @sql varchar(8000),@tbname varchar(50)

 

--首先將excel表內容導入到一個全局臨時表

select @tbname='[##temp'+cast(newid() as varchar(40))+']'

,@sql='select 姓名,銀行賬號1=left(銀行賬號,8),銀行賬號2=right(銀行賬號,8)

into '+@tbname+' from

opendatasource(''MICROSOFT.JET.OLEDB.4.0''

,''Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls''

)...[Sheet1$]'

exec(@sql)

 

--然后用bcp從全局臨時表導出到文本文件

set @sql='bcp "'+@tbname+'" out "c:\aa.txt" /S"(local)" /P"" /c'

exec master..xp_cmdshell @sql

 

--刪除臨時表

exec('drop table '+@tbname)

 

 

bcp將文件導入導出到數據庫的存儲過程:

 

 

/*--bcp-二進制文件的導入導出

 

支持image,text,ntext字段的導入/導出

image適合於二進制文件;text,ntext適合於文本數據文件

 

注意:導入時,將覆蓋滿足條件的所有行

   導出時,將把所有滿足條件的行也出到指定文件中

 

此存儲過程僅用bcp實現

鄒建 2003.08-----------------*/

 

/*--調用示例

--數據導出

exec p_binaryIO 'zj','','','acc_演示數據..tb','img','c:\zj1.dat'

 

--數據導出

exec p_binaryIO 'zj','','','acc_演示數據..tb','img','c:\zj1.dat','',0

--*/

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_binaryIO]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[p_binaryIO]

GO

 

Create proc p_binaryIO

@servename varchar (30),--服務器名稱

@username varchar (30), --用戶名

@password varchar (30), --密碼

@tbname varchar (500),  --數據庫..表名

@fdname varchar (30),   --字段名

@fname varchar (1000), --目錄+文件名,處理過程中要使用/覆蓋:@filename+.bak

@tj varchar (1000)='',   --處理條件.對於數據導入,如果條件中包含@fdname,請指定表名前綴

@isout bit=1    --1導出((默認),0導入

AS

declare @fname_in varchar(1000) --bcp處理應答文件名

,@fsize varchar(20)    --要處理的文件的大小

,@m_tbname varchar(50)   --臨時表名

,@sql varchar(8000)

 

--則取得導入文件的大小

if @isout=1

set @fsize='0'

else

begin

create table #tb(可選名 varchar(20),大小 int

   ,創建日期 varchar(10),創建時間 varchar(20)

   ,上次寫操作日期 varchar(10),上次寫操作時間 varchar(20)

   ,上次訪問日期 varchar(10),上次訪問時間 varchar(20),特性 int)

insert into #tb

exec master..xp_getfiledetails @fname

select @fsize=大小 from #tb

drop table #tb

if @fsize is null

begin

   print '文件未找到'

   return

end

 

end

 

--生成數據處理應答文件

set @m_tbname='[##temp'+cast(newid() as varchar(40))+']'

set @sql='select * into '+@m_tbname+' from(

select null as 類型

union all select 0 as 前綴

union all select '+@fsize+' as 長度

union all select null as 結束

union all select null as 格式

) a'

exec(@sql)

select @fname_in=@fname+'_temp'

,@sql='bcp "'+@m_tbname+'" out "'+@fname_in

+'" /S"'+@servename

+case when isnull(@username,'')='' then ''

   else '" /U"'+@username end

+'" /P"'+isnull(@password,'')+'" /c'

exec master..xp_cmdshell @sql

--刪除臨時表

set @sql='drop table '+@m_tbname

exec(@sql)

 

if @isout=1

begin

set @sql='bcp "select top 1 '+@fdname+' from '

   +@tbname+case isnull(@tj,'') when '' then ''

    else ' where '+@tj end

   +'" queryout "'+@fname

   +'" /S"'+@servename

   +case when isnull(@username,'')='' then ''

    else '" /U"'+@username end

   +'" /P"'+isnull(@password,'')

   +'" /i"'+@fname_in+'"'

exec master..xp_cmdshell @sql

end

else

begin

--為數據導入准備臨時表

set @sql='select top 0 '+@fdname+' into '

   +@m_tbname+' from ' +@tbname

exec(@sql)

 

--將數據導入到臨時表

set @sql='bcp "'+@m_tbname+'" in "'+@fname

   +'" /S"'+@servename

   +case when isnull(@username,'')='' then ''

    else '" /U"'+@username end

   +'" /P"'+isnull(@password,'')

   +'" /i"'+@fname_in+'"'

exec master..xp_cmdshell @sql

 

--將數據導入到正式表中

set @sql='update '+@tbname

   +' set '+@fdname+'=b.'+@fdname

   +' from '+@tbname+' a,'

   +@m_tbname+' b'

   +case isnull(@tj,'') when '' then ''

    else ' where '+@tj end

exec(@sql)

 

--刪除數據處理臨時表

set @sql='drop table '+@m_tbname

end

 

--刪除數據處理應答文件

set @sql='del '+@fname_in

exec master..xp_cmdshell @sql

 

go

 

 

/** 導入文本文件

EXEC master..xp_cmdshell 'bcp "dbname..tablename" in c:\DT.txt -c -Sservername -Usa -Ppassword'

 

改為如下,不需引號

EXEC master..xp_cmdshell 'bcp dbname..tablename in c:\DT.txt -c -Sservername -Usa -Ppassword'

 

/** 導出文本文件

EXEC master..xp_cmdshell 'bcp "dbname..tablename" out c:\DT.txt -c -Sservername -Usa -Ppassword'

此句需加引號


sql常見面試題

sql理論題

1.觸發器的作用?

 

 答:觸發器是一中特殊的存儲過程,主要是通過事件來觸發而被執行的。它可以強化約束,來維護數據的完整性和一致性,可以跟蹤數據庫內的操作從而不允許未經許可的更新和變化。可以聯級運算。如,某表上的觸發器上包含對另一個表的數據操作,而該操作又會導致該表觸發器被觸發。

 

2什么是存儲過程?用什么來調用?

 

答:存儲過程是一個預編譯的SQL語句,優點是允許模塊化的設計,就是說只需創建一次,以后在該程序中就可以調用多次。如果某次操作需要執行多次SQL,使用存儲過程比單純SQL語句執行要快。可以用一個命令對象來調用存儲過程。

 

3。索引的作用?和它的優點缺點是什么?

答:索引就一種特殊的查詢表,數據庫的搜索引擎可以利用它加速對數據的檢索。它很類似與現實生活中書的目錄,不需要查詢整本書內容就可以找到想要的數據。索引可以是唯一的,創建索引允許指定單個列或者是多個列。缺點是它減慢了數據錄入的速度,同時也增加了數據庫的尺寸大小。

 

3。什么是內存泄漏?

答:一般我們所說的內存泄漏指的是堆內存的泄漏。堆內存是程序從堆中為其分配的,大小任意的,使用完后要顯示釋放內存。當應用程序用關鍵字new等創建對象時,就從堆中為它分配一塊內存,使用完后程序調用free或者delete釋放該內存,否則就說該內存就不能被使用,我們就說該內存被泄漏了。

 

4維護數據庫的完整性和一致性,你喜歡用觸發器還是自寫業務邏輯?為什么?

 

答:我是這樣做的,盡可能使用約束,如check,主鍵,外鍵,非空字段等來約束,這樣做效率最高,也最方便。其次是使用觸發器,這種方法可以保證,無論什么業務系統訪問數據庫都可以保證數據的完整新和一致性。最后考慮的是自寫業務邏輯,但這樣做麻煩,編程復雜,效率低下。

 

5什么是事務?什么是鎖?

答:事務就是被綁定在一起作為一個邏輯工作單元的SQL語句分組,如果任何一個語句操作失敗那么整個操作就被失敗,以后操作就會回滾到操作前狀態,或者是上有個節點。為了確保要么執行,要么不執行,就可以使用事務。要將有組語句作為事務考慮,就需要通過ACID測試,即原子性,一致性,隔離性和持久性。

 

 鎖:在所以的DBMS中,鎖是實現事務的關鍵,鎖可以保證事務的完整性和並發性。與現實生活中鎖一樣,它可以使某些數據的擁有者,在某段時間內不能使用某些數據或數據結構。當然鎖還分級別的。

 

6什么叫視圖?游標是什么

答:視圖是一種虛擬的表,具有和物理表相同的功能。可以對視圖進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。對視圖的修改不影響基本表。它使得我們獲取數據更容易,相比多表查詢。

 

  游標:是對查詢出來的結果集作為一個單元來有效的處理。游標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行。可以對結果集當前行做修改。一般不使用游標,但是需要逐條處理數據的時候,游標顯得十分重要。

 

7。為管理業務培訓信息,建立3個表:

     S(S#,SN,SD,SA)S#,SN,SD,SA分別代表學號,學員姓名,所屬單位,學員年齡

     C(C#,CN)C#,CN分別代表課程編號,課程名稱

     SC(S#,C#,G) S#,C#,G分別代表學號,所選的課程編號,學習成績

 1)使用標准SQL嵌套語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名?

      答案:select s# ,sn from s where S# in(select S# from c,sc where c.c#=sc.c# and  cn=’稅收基礎’)

 (2) 使用標准SQL嵌套語句查詢選修課程編號為’C2的學員姓名和所屬單位?

答:select sn,sd from s,sc where s.s#=sc.s# and sc.c#=c2

 (3) 使用標准SQL嵌套語句查詢不選修課程編號為’C5的學員姓名和所屬單位?

答:select sn,sd from s where s# not in(select s# from sc where c#=c5)

 

 (4)查詢選修了課程的學員人數

答:select 學員人數=count(distinct s#) from sc

 

(5) 查詢選修課程超過5門的學員學號和所屬單位?

答:select sn,sd from s where s# in(select s# from sc group by s# having count(distinct  c#)>5)

 

是查詢A(ID,Name)表中第3140條記錄,ID作為主鍵可能是不是連續增長的列,完整的查詢語句如下:

 

select top 10 * from A where ID >(select max(ID) from (select top 30 ID from A order by A

 

) T) order by A

 

要求是查詢表A中存在ID重復三次以上的記錄,完整的查詢語句如下:

select * from(select count(ID) as count from table group by ID)T where T.count>3

 

create table testtable1

(

 id int IDENTITY,

 department varchar(12)

)

 

select * from testtable1

insert into testtable1 values('設計')

insert into testtable1 values('市場')

insert into testtable1 values('售后')

/*

結果

id department

1   設計

2   市場

3   售后

*/

create table testtable2

(

 id int IDENTITY,

 dptID int,

 name varchar(12)

)

insert into testtable2 values(1,'張三')

insert into testtable2 values(1,'李四')

insert into testtable2 values(2,'王五')

insert into testtable2 values(3,'彭六')

insert into testtable2 values(4,'陳七')

/*

用一條SQL語句,怎么顯示如下結果

id dptID department name

1   1      設計        張三

2   1      設計        李四

3   2      市場        王五

4   3      售后        彭六

5   4      黑人        陳七

*/

 

答案是:

 

SELECT testtable2.* , ISNULL(department,'黑人')

FROM testtable1 right join testtable2 on testtable2.dptID = testtable1.ID

 

 

 

在面試應聘的SQL Server數據庫開發人員時,我運用了一套標准的基准技術問題。下面這些問題是我覺得能夠真正有助於淘汰不合格應聘者的問題。它們按照從易到難的順序排列。當你問到關於主鍵和外鍵的問題時,后面的問題都十分有難度,因為答案可能會更難解釋和說明,尤其是在面試的情形下。

 

你能向我簡要敘述一下SQL Server 2000中使用的一些數據庫對象嗎?

 

你希望聽到的答案包括這樣一些對象:表格、視圖、用戶定義的函數,以及存儲過程;如果他們還能夠提到像觸發器這樣的對象就更好了。如果應聘者不能回答這個基本的問題,那么這不是一個好兆頭。

 

NULL是什么意思?

NULL()這個值是數據庫世界里一個非常難纏的東西,所以有不少應聘者會在這個問題上跌跟頭您也不要覺得意外。 NULL這個值表示UNKNOWN(未知):它不表示“”(空字符串)。假設您的SQL Server數據庫里有ANSI_NULLS,當然在默認情況下會有,對NULL這個值的任何比較都會生產一個NULL值。您不能把任何值與一個 UNKNOWN值進行比較,並在邏輯上希望獲得一個答案。您必須使用IS NULL操作符。

 

什么是索引?SQL Server 2000里有什么類型的索引?

 

任何有經驗的數據庫開發人員都應該能夠很輕易地回答這個問題。一些經驗不太多的開發人員能夠回答這個問題,但是有些地方會說不清楚。簡單地說,索引是一個數據結構,用來快速訪問數據庫表格或者視圖里的數據。在SQL Server里,它們有兩種形式:聚集索引和非聚集索引。聚集索引在索引的葉級保存數據。這意味着不論聚集索引里有表格的哪個(或哪些)字段,這些字段都會按順序被保存在表格。由於存在這種排序,所以每個表格只會有一個聚集索引。非聚集索引在索引的葉級有一個行標識符。這個行標識符是一個指向磁盤上數據的指針。它允許每個表格有多個非聚集索引。

 

什么是主鍵?什么是外鍵?

 

主鍵是表格里的(一個或多個)字段,只用來定義表格里的行;主鍵里的值總是唯一的。外鍵是一個用來建立兩個表格之間關系的約束。這種關系一般都涉及一個表格里的主鍵字段與另外一個表格(盡管可能是同一個表格)里的一系列相連的字段。那么這些相連的字段就是外鍵。

 

什么是觸發器?SQL Server 2000有什么不同類型的觸發器?

 

讓未來的數據庫開發人員知道可用的觸發器類型以及如何實現它們是非常有益的。觸發器是一種專用類型的存儲過程,它被捆綁到SQL Server 2000的表格或者視圖上。在SQL Server 2000里,有INSTEAD-OFAFTER兩種觸發器。INSTEAD-OF觸發器是替代數據操控語言(Data Manipulation

 

LanguageDML)語句對表格執行語句的存儲過程。例如,如果我有一個用於TableAINSTEAD-OF-UPDATE

 

觸發器,同時對這個表格執行一個更新語句,那么INSTEAD-OF-UPDATE觸發器里的代碼會執行,而不是我執行的更新語句則不會執行操作。

 

AFTER觸發器要在DML語句在數據庫里使用之后才執行。這些類型的觸發器對於監視發生在數據庫表格里的數據變化十分好用。

 

您如何確一個帶有名為Fld1字段的TableB表格里只具有Fld1字段里的那些值,而這些值同時在名為TableA的表格的Fld1字段里?

 

這個與關系相關的問題有兩個可能的答案。第一個答案(而且是您希望聽到的答案)是使用外鍵限制。外鍵限制用來維護引用的完整性。它被用來確保表格里的字段只保存有已經在不同的(或者相同的)表格里的另一個字段里定義了的值。這個字段就是候選鍵(通常是另外一個表格的主鍵)

 

另外一種答案是觸發器。觸發器可以被用來保證以另外一種方式實現與限制相同的作用,但是它非常難設置與維護,而且性能一般都很糟糕。由於這個原因,微軟建議開發人員使用外鍵限制而不是觸發器來維護引用的完整性。

 

對一個投入使用的在線事務處理表格有過多索引需要有什么樣的性能考慮?

 

你正在尋找進行與數據操控有關的應聘人員。對一個表格的索引越多,數據庫引擎用來更新、插入或者刪除數據所需要的時間就越多,因為在數據操控發生的時候索引也必須要維護。

 

你可以用什么來確保表格里的字段只接受特定范圍里的值?

 

這個問題可以用多種方式來回答,但是只有一個答案是“好”答案。您希望聽到的回答是Check限制,它在數據庫表格里被定義,用來限制輸入該列的值。

 

觸發器也可以被用來限制數據庫表格里的字段能夠接受的值,但是這種辦法要求觸發器在表格里被定義,這可能會在某些情況下影響到性能。因此,微軟建議使用Check限制而不是其他的方式來限制域的完整性。

 

如果應聘者能夠正確地回答這個問題,那么他的機會就非常大了,因為這表明他們具有使用存儲過程的經驗。

 

返回參數總是由存儲過程返回,它用來表示存儲過程是成功還是失敗。返回參數總是INT數據類型。

 

OUTPUT參數明確要求由開發人員來指定,它可以返回其他類型的數據,例如字符型和數值型的值。(可以用作輸出參數的數據類型是有一些限制的。)您可以在一個存儲過程里使用多個OUTPUT參數,而您只能夠使用一個返回參數。

 

什么是相關子查詢?如何使用這些查詢?

 

經驗更加豐富的開發人員將能夠准確地描述這種類型的查詢。相關子查詢是一種包含子查詢的特殊類型的查詢。查詢里包含的子查詢會真正請求外部查詢的值,從而形成一個類似於循環的狀況。

 

什么是SQL注入式攻擊?

所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務器執行惡意的SQL命令。在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態SQL命令,或作為存儲過程的輸入參數,這類表單特別容易受到SQL注入式攻擊。常見的SQL注入式攻擊過程類如:

某個ASP.NET Web應用有一個登錄頁面,這個登錄頁面控制着用戶是否有權訪問應用,它要求用戶輸入一個名稱和密碼。

登錄頁面中輸入的內容將直接用來構造動態的SQL命令,或者直接用作存儲過程的參數。下面是ASP.NET應用構造查詢的一個例子:

System.Text.StringBuilder query = new System.Text.StringBuilder(
   "SELECT * from Users WHERE login = '")
   .Append(txtLogin.Text).Append("' AND password='")
   .Append(txtPassword.Text).Append("'");


攻擊者在用戶名字和密碼輸入框中輸入"'或'1'='1"之類的內容。

用戶輸入的內容提交給服務器之后,服務器運行上面的ASP.NET代碼構造出查詢用戶的SQL命令,但由於攻擊者輸入的內容非常特殊,所以最后得到的SQL命令變成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。

服務器執行查詢或存儲過程,將用戶輸入的身份信息和服務器中保存的身份信息進行對比。

由於SQL命令實際上已被注入式攻擊修改,已經不能真正驗證用戶身份,所以系統會錯誤地授權給攻擊者。

如果攻擊者知道應用會將表單中輸入的內容直接用於驗證身份的查詢,他就會嘗試輸入某些特殊的SQL字符串篡改查詢改變其原來的功能,欺騙系統授予訪問權限。

系統環境不同,攻擊者可能造成的損害也不同,這主要由應用訪問數據庫的安全權限決定。如果用戶的帳戶具有管理員或其他比較高級的權限,攻擊者就可能對數據庫的表執行各種他想要做的操作,包括添加、刪除或更新數據,甚至可能直接刪除表

如何防范SQL注入式攻擊?

好在要防止ASP.NET應用被SQL注入式攻擊闖入並不是一件特別困難的事情,只要在利用表單輸入的內容構造SQL命令之前,把所有輸入內容過濾一番就可以了。過濾輸入內容可以按多種方式進行。

對於動態構造SQL查詢的場合,可以使用下面的技術:

第一:替換單引號,即把所有單獨出現的單引號改成兩個單引號,防止攻擊者修改SQL命令的含義。再來看前面的例子,"SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'"顯然會得到與"SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'"不同的結果。

第二:刪除用戶輸入內容中的所有連字符,防止攻擊者構造出類如"SELECT * from Users WHERE login = 'mas' -- AND password =''"之類的查詢,因為這類查詢的后半部分已經被注釋掉,不再有效,攻擊者只要知道一個合法的用戶登錄名稱,根本不需要知道用戶的密碼就可以順利獲得訪問權限。

第三:對於用來執行查詢的數據庫帳戶,限制其權限。用不同的用戶帳戶執行查詢、插入、更新、刪除操作。由於隔離了不同帳戶可執行的操作,因而也就防止了原本用於執行SELECT命令的地方卻被用於執行INSERT、UPDATE或DELETE命令。

用存儲過程來執行所有的查詢。SQL參數的傳遞方式將防止攻擊者利用單引號和連字符實施攻擊。此外,它還使得數據庫權限可以限制到只允許特定的存儲過程執行,所有的用戶輸入必須遵從被調用的存儲過程的安全上下文,這樣就很難再發生注入式攻擊了。

限制表單或查詢字符串輸入的長度。如果用戶的登錄名字最多只有10個字符,那么不要認可表單中輸入的10個以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。

檢查用戶輸入的合法性,確信輸入的內容只包含合法的數據。數據檢查應當在客戶端和服務器端都執行——之所以要執行服務器端驗證,是為了彌補客戶端驗證機制脆弱的安全性。

在客戶端,攻擊者完全有可能獲得網頁的源代碼,修改驗證合法性的腳本(或者直接刪除腳本),然后將非法內容通過修改后的表單提交給服務器。因此,要保證驗證操作確實已經執行,唯一的辦法就是在服務器端也執行驗證。你可以使用許多內建的驗證對象,例如 RegularExpressionValidator,它們能夠自動生成驗證用的客戶端腳本,當然你也可以插入服務器端的方法調用。如果找不到現成的驗證對象,你可以通過CustomValidator自己創建一個。

將用戶登錄名稱、密碼等數據加密保存。加密用戶輸入的數據,然后再將它與數據庫中保存的數據比較,這相當於對用戶輸入的數據進行了"消毒"處理,用戶輸入的數據不再對數據庫有任何特殊的意義,從而也就防止了攻擊者注入SQL命令。 System.Web.Security.FormsAuthentication類有一個 HashPasswordForStoringInConfigFile,非常適合於對輸入數據進行消毒處理。

檢查提取數據的查詢所返回的記錄數量。如果程序只要求返回一個記錄,但實際返回的記錄卻超過一行,那就當作出錯處理

 

 

Sql常見題目

為管理崗位業務培訓信息,建立3個表:

S (S#,SN,SD,SA) S#,SN,SD,SA 分別代表學號、學員姓名、所屬單位、學員年齡

C (C#,CN ) C#,CN 分別代表課程編號、課程名稱

SC ( S#,C#,G ) S#,C#,G 分別代表學號、所選修的課程編號、學習成績

1. 使用標准SQL嵌套語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM C,SC Where C.[C#]=SC.[C#] AND CN=N'稅收基礎')

2. 使用標准SQL嵌套語句查詢選修課程編號為’C2的學員姓名和所屬單位

--實現代碼:

Select S.SN,S.SD FROM S,SC Where S.[S#]=SC.[S#] AND SC.[C#]='C2'

3. 使用標准SQL嵌套語句查詢不選修課程編號為’C5的學員姓名和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] NOT IN( Select [S#] FROM SC Where [C#]='C5')

4. 使用標准SQL嵌套語句查詢選修全部課程的學員姓名和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM SC RIGHT JOIN C ON SC.[C#]=C.[C#] GROUP BY [S#] HAVING COUNT(*)=COUNT([S#]))

5. 查詢選修了課程的學員人數

--實現代碼:

Select 學員人數=COUNT(DISTINCT [S#]) FROM SC

6. 查詢選修課程超過5門的學員學號和所屬單位

--實現代碼:

Select SN,SD FROM S Where [S#] IN( Select [S#] FROM SC GROUP BY [S#] HAVING COUNT(DISTINCT [C#])>5)

題目2:

問題描述:

S (SNO,SNAME) 學生關系。SNO 為學號,SNAME 為姓名

C (CNO,CNAME,CTEACHER) 課程關系。CNO 為課程號,CNAME 為課程名,CTEACHER 為任課教師

SC(SNO,CNO,SCGRADE) 選課關系。SCGRADE 為成績

1. 找出沒有選修過“李明”老師講授課程的所有學生姓名

--實現代碼:

Select SNAME FROM S Where NOT EXISTS( Select * FROM SC,C Where SC.CNO=C.CNO AND CNAME='李明' AND SC.SNO=S.SNO)

2. 列出有二門以上(含兩門)不及格課程的學生姓名及其平均成績

--實現代碼:

Select S.SNO,S.SNAME,AVG_SCGRADE=AVG(SC.SCGRADE) FROM S,SC,( Select SNO FROM SC Where SCGRADE<60 GROUP BY SNO HAVING COUNT(DISTINCT CNO)>=2 )A Where S.SNO=A.SNO AND SC.SNO=A.SNO GROUP BY S.SNO,S.SNAME

3. 列出既學過“1號課程,又學過“2號課程的所有學生姓名

--實現代碼:

Select S.SNO,S.SNAME FROM S,( Select SC.SNO FROM SC,C Where SC.CNO=C.CNO AND C.CNAME IN('1','2') GROUP BY SNO HAVING COUNT(DISTINCT CNO)=2 )SC Where S.SNO=SC.SNO

4. 列出“1號課成績比“2號同學該門課成績高的所有學生的學號

--實現代碼:

Select S.SNO,S.SNAME FROM S,( Select SC1.SNO FROM SC SC1,C C1,SC SC2,C C2 Where SC1.CNO=C1.CNO AND C1.NAME='1' AND SC2.CNO=C2.CNO AND C2.NAME='2' AND SC1.SCGRADE>SC2.SCGRADE )SC Where S.SNO=SC.SNO

5. 列出“1號課成績比“2號課成績高的所有學生的學號及其“1號課和“2號課的成績

--實現代碼:

Select S.SNO,S.SNAME,SC.[1號課成績],SC.[2號課成績] FROM S,( Select SC1.SNO,[1號課成績]=SC1.SCGRADE,[2號課成績]=SC2.SCGRADE FROM SC SC1,C C1,SC SC2,C C2 Where SC1.CNO=C1.CNO AND C1.NAME='1' AND SC2.CNO=C2.CNO AND C2.NAME='2' AND SC1.SCGRADE>SC2.SCGRADE )SC Where S.SNO=SC.SNO

 

 

求其中同一個號碼的兩次通話之間間隔大於10秒的通話記錄ID

例如:678910條記錄均符合

ID 主叫號碼 被叫號碼      通話起始時間            通話結束時間            通話時長

1 98290000 0215466546656 2007-02-01 09:49:53.000 2007-02-01 09:50:16.000 23

2 98290000 021546654666 2007-02-01 09:50:29.000 2007-02-01 09:50:41.000 12

3 98290000 021546654666 2007-02-01 09:50:58.000 2007-02-01 09:51:12.000 14

4 68290900 0755133329866 2007-02-01 10:04:31.000 2007-02-01 10:07:13.000 162

5 78290000 0755255708638 2007-02-01 10:48:26.000 2007-02-01 10:49:23.000 57

6 78290000 0755821119109 2007-02-01 10:49:39.000 2007-02-01 10:52:55.000 196

7 78290000 035730928370 2007-02-01 11:30:45.000 2007-02-01 11:31:58.000 73

8 78290000 0871138889904 2007-02-01 11:33:47.000 2007-02-01 11:35:00.000 73

9 68290000 035730928379 2007-02-01 11:52:20.000 2007-02-01 11:54:56.000 156

10 68290000 0298521811199 2007-02-01 12:44:45.000 2007-02-01 12:45:04.000 19

 

答案:

SELECT DISTINCT a.* FROM dbo.hc a left join dbo.hc b

ON a.主叫號碼=b.主叫號碼

WHERE a.id<>b.id AND (DATEDIFF(second,a.通話起始時間,b.通話結束時間)>10 AND

DATEDIFF(second,b.通話起始時間,a.通話結束時間)>10)

 

 

Sql Server關於按周統計的問題

統計Sql Server里一個銷售明細表里某個時間段的銷售額,而且要按周進行比較,以下是該語句的寫法:

 

select sum(銷售金額), datename(week, 銷售日期-1) from sales where 銷售日期 betwee begindate and enddate group by datename(week, 銷售日期-1)

 

注意:這里之所以要把銷售日期-1是因為sql server默認的一周的第一天是星期天,而我們習慣的統計是以星期一到星期天計算的,所以減一。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM