1. 程式人生 > >SQL經典面試題目總結

SQL經典面試題目總結

Sql常用語法

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

SQL分類:

DDL—資料定義語言(CREATE,ALTER,DROP,DECLARE)

DML—資料操縱語言(SELECT,DELETE,UPDATE,INSERT)

DCL—資料控制語言(GRANT,REVOKE,COMMIT,ROLLBACK) 首先,簡要介紹基礎語句:

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],..)根據已有的表建立新表:

A:create table tab_new like tab_old (使用舊錶建立新表)

B:create 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、說明:使用外連線

A、left 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

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

C:full 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、說明:子查詢(表名1:a 表名2:b)

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、說明:外連線查詢(表名1:a 表名2:b)

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、說明:線上檢視查詢(表名1:a )

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 中但不在 TableB和TableC 中的行並消除所有重複行而派生出一個結果表

(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、說明:列示type、vender、pcs欄位,以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、說明:選擇從10到15的記錄

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 '[email protected]_key+' ,count(*) from ' [email protected]_name +' group by ' [email protected]_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 [email protected]_key

if @type=56

select @sql = 'delete from '[email protected]_name+' where ' + @f_key+' = '+ @id

if @type=167

select @sql = 'delete from '[email protected]_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 '[email protected]_key+' ,count(*) from ' [email protected]_name +' group by ' [email protected]_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 [email protected]_key

if @type=56

select @sql = 'delete from '[email protected]_name+' where ' + @f_key+' = '+ @id

if @type=167

select @sql = 'delete from '[email protected]_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 @[email protected]+','+cast(pid as varchar) from 表A where [email protected]

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 Server)SQL語句匯入匯出大全

/******* 匯出到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 '[email protected]

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

+' "'[email protected]+'" /w'

+' /S '[email protected]

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

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

exec master..xp_cmdshell @sql

end

else

begin --匯出整個資料庫,定義遊標,取出所有的使用者表

declare @m_tbname varchar(250)

if right(@filename,1)<>'\' set @[email protected]+'\'

set @m_tbname='declare #tb cursor for select name from '[email protected]+'..sysobjects where xtype=''U'''

exec(@m_tbname)

open #tb

fetch next from #tb into @m_tbname

while @@fetch_status=0

begin

set @sql='bcp '[email protected]+'..'[email protected]_tbname

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

+' "'[email protected][email protected]_tbname+'.txt " /w'

+' /S '[email protected]

+case when isnull(@username,'')='' then '' else ' /U '[email protected] 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 '[email protected]+' 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 "'[email protected]+'" out "c:\aa.txt" /S"(local)" /P"" /c'

exec master..xp_cmdshell @sql

--刪除臨時表

exec('drop table '[email protected])

用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 '[email protected]_tbname+' from(

select null as 型別

union all select 0 as 字首

union all select '[email protected]+' as 長度

union all select null as 結束

union all select null as 格式

) a'

exec(@sql)

select @[email protected]+'_temp'

,@sql='bcp "'[email protected]_tbname+'" out "'[email protected]_in

+'" /S"'[email protected]

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

else '" /U"'[email protected] end

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

exec master..xp_cmdshell @sql

--刪除臨時表

set @sql='drop table '[email protected]_tbname

exec(@sql)

if @isout=1

begin

set @sql='bcp "select top 1 '[email protected]+' from '

[email protected]+case isnull(@tj,'') when '' then ''

else ' where '[email protected] end

+'" queryout "'[email protected]

+'" /S"'[email protected]

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

else '" /U"'[email protected] end

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

+'" /i"'[email protected]_in+'"'

exec master..xp_cmdshell @sql

end

else

begin

--為資料匯入準備臨時表

set @sql='select top 0 '[email protected]+' into '

[email protected]_tbname+' from ' [email protected]

exec(@sql)

--將資料匯入到臨時表

set @sql='bcp "'[email protected]_tbname+'" in "'[email protected]

+'" /S"'[email protected]

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

else '" /U"'[email protected] end

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

+'" /i"'[email protected]_in+'"'

exec master..xp_cmdshell @sql

--將資料匯入到正式表中

set @sql='update '[email protected]

+' set '[email protected]+'=b.'[email protected]

+' from '[email protected]+' a,'

[email protected]_tbname+' b'

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

else ' where '[email protected] end

exec(@sql)

--刪除資料處理臨時表

set @sql='drop table '[email protected]_tbname

end

--刪除資料處理應答檔案

set @sql='del '[email protected]_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)表中第31至40條記錄,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-OF和AFTER兩種觸發器。INSTEAD-OF觸發器是替代資料操控語言(Data Manipulation

Language,DML)語句對錶格執行語句的儲存過程。例如,如果我有一個用於TableA的INSTEAD-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

例如:6,7,8,9,10條記錄均符合

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)

注意:這裡