Sql經常使用語法、使用技巧和麪試題

下列語句部分是Mssql語句,不能夠在access中使用。面試

 

SQL分類:sql

DDL—數據定義語言(CREATE,ALTER,DROP,DECLARE)shell

DML—數據操縱語言(SELECT,DELETE,UPDATE,INSERT)數據庫

DCL—數據控制語言(GRANT,REVOKE,COMMIT,ROLLBACK) 首先,簡要介紹基礎語句:編程

一、說明:建立數據庫c#

CREATE DATABASE database-name安全

 

二、說明:刪除數據庫服務器

drop database dbname數據結構

 

三、說明:備份sql server併發

--- 建立 備份數據的 device

USE master

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

--- 開始 備份

BACKUP DATABASE pubs TO testBack

 

四、說明:建立新表

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

 

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

 

六、說明:增長一個列

 

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

 

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

 

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

 

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

 

十、說明:幾個簡單的基本的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

 

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

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),不消除重複行。 注:使用運算詞的幾個查詢結果行必須是一致的。

 

十二、說明:使用外鏈接

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語句

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

 

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

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

 

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

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

 

四、說明:子查詢(表名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)

 

五、說明:顯示文章、提交人和最後回覆時間

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

 

六、說明:外鏈接查詢(表名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

 

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

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

 

八、說明: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

 

九、說明:in 的使用方法

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

 

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

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

 

十一、說明:四表聯查問題:

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 .....

 

十二、說明:日程安排提早五分鐘提醒

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

 

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

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

 

1四、說明:前10條記錄

select top 10 * form table1 where 範圍

 

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

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

 

1六、說明:包括全部在 TableA 中但不在 TableB和TableC 中的行並消除全部重複行而派生出一個結果表

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

 

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

select top 10 * from tablename order by newid()

 

1八、說明:隨機選擇記錄

select newid()

 

1九、說明:刪除重複記錄

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

 

20、說明:列出數據庫裏全部的表名

select name from sysobjects where type='U'

 

2一、說明:列出表裏的全部的

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

 

2二、說明:列示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

 

2三、說明:初始化表table1

TRUNCATE TABLE table1

 

2四、說明:選擇從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 '+@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

 

二、將不重複的記錄記入temp1表:

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

 

三、做一個包含全部不重複記錄的表:

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

 

四、刪除重複表:

delete [表名]

 

五、恢復表:

insert [表名] select * from temp2

 

六、刪除臨時表:

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 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 '+@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)表中第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

例如: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默認的一週的第一天是星期天,而咱們習慣的統計是以星期一到星期天計算的,因此減一。

相關文章
相關標籤/搜索