Fork me on GitHub
sql proc1

 

-动态语句1
declare @sql nvarchar(4000)
declare @wheresql  varchar(1000)
set  @wheresql=' and 订单号=''001'''
set @sql = 'select * from tb where 1=1 '+ @wheresql
exec(@sql)

--动态语句2 
declare @sql nvarchar(4000)
declare @wheresql  varchar(1000)
declare @日志ID int
set  @wheresql=' and 订单号=''001'''
set @sql = 'select @日志ID=日志ID from tb where 1=1 '+ @wheresql
exec sp_executesql @sql, N'@日志ID int output',@日志ID output
select @日志ID

 

 

动态sql语句基本语法 
1 :普通SQL语句可以用Exec执行 

eg: Select * from tableName 
 Exec('select * from tableName') 
 Exec sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N 

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL 

eg: 
declare @fname varchar(20) 
set @fname = 'FiledName' 
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。 
Exec('select ' + @fname + ' from tableName') -- 请注意 加号前后的 单引号的边上加空格 

当然将字符串改成变量的形式也可 
declare @fname varchar(20) 
set @fname = 'FiledName' --设置字段名 

declare @s varchar(1000) 
set @s = 'select ' + @fname + ' from tableName' 
Exec(@s) -- 成功 
exec sp_executesql @s -- 此句会报错 

declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000) 
set @s = 'select ' + @fname + ' from tableName' 
Exec(@s) -- 成功 
exec sp_executesql @s -- 此句正确 

3. 输出参数 
declare @num int, 
 @sqls nvarchar(4000) 
set @sqls='select count(*) from tableName' 
exec(@sqls) 
--如何将exec执行结果放入变量中? 

declare @num int, 
 @sqls nvarchar(4000) 
set @sqls='select @a=count(*) from tableName ' 
exec sp_executesql @sqls,N'@a int output',@num output 
select @num 












--1. 构造使用IN子句的动态Transact-SQL方法进行编号查询

--a. 要查询的字段类型是数字型

--查询的值列表
DECLARE @idlist varchar(100)
SET @idlist='1,2,3'

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
GO

--b. 要查询的字段类型是字符型
--查询的值列表已经加上了字符串边界符
DECLARE @idlist varchar(100)
SET @idlist='''a'',''b''''a'',''c'''

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
GO

--查询的值列表没有字符串边界符
DECLARE @idlist varchar(100)
SET @idlist='a,b''a,c'

--由于是字段类型是,所以在拼接时,必须为其加上字符串边界符(')
DECLARE @s varchar(1000)
SET @s=''''
    +REPLACE(REPLACE(@idlist,'''',''''''),',',''',''')
    +''''

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@s+')')
GO

/*=====================================================*/


--2. 使用LIKE或者PATINDEX进行编号查询
--查询的值列表
DECLARE @idlist varchar(100)
SET @idlist='1,2,3'

--查询
SELECT * FROM tbname WHERE CHARINDEX(','+RTRIM(fdname)+',',','+@idlist+',')>0
SELECT * FROM tbname WHERE PATINDEX('%,'+RTRIM(fdname)+',%',','+@idlist+',')>0
SELECT * FROM tbname WHERE ','+@idlist+',' LIKE '%,'+RTRIM(fdname)+',%'
GO

/*=====================================================*/


--3. 编号查询中常见的错误
--a. 最容易犯的错误:表达式充当表达式列表。
DECLARE @s varchar(100)
SET @s='1'
SELECT id,name FROM sysobjects WHERE id IN(@s)
/*--结果
id          name 
---------------- ------------
1           sysobjects
--*/

SET @s='1,2,3'
SELECT id,name FROM sysobjects WHERE id IN(@s)
/*--结果
服务器: 消息 245,级别 16,状态 1,行 3
将 varchar 值 '1,2,3' 转换为数据类型为 int 的列时发生语法错误。
--*/
GO

--b. 生成动态Transact-SQL语句时忽略了数据类型。
DECLARE @s varchar(100)
SET @s='U,S'
EXEC('SELECT id,name FROM sysobjects WHERE id IN('+@s+')')
/*--结果:
服务器: 消息 207,级别 16,状态 3,行 1
列名 'S' 无效。
服务器: 消息 207,级别 16,状态 1,行 1
列名 'U' 无效。
--*/
GO

--c. 忽略了比较的精确性问题。
--要查询的数据
DECLARE @t TABLE(col varchar(10))
INSERT @t SELECT '1'
UNION ALL SELECT '11'
UNION ALL SELECT '111'
UNION ALL SELECT '22'

--查询
DECLARE @s varchar(100)
SET @s='111,22'
SELECT * FROM @t WHERE CHARINDEX(col,@s)>0
/*--结果
col        
---------- 
1
11
111
22
-*/
GO

完整示例
http://blog.csdn.net/xys_777/archive/2010/06/24/5690909.aspx

 

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

--
--
--
--
ALTER PROCEDURE [dbo].[SP_GetList] 
(  
    @start int,                 ---记录开始数
    @end int,                   ---记录结束数  结束记录为0时返回所有结果集
    @tablename varchar(50),     ---表名
    @idname varchar(50),        ---ID列明
    @condition varchar(2000),   ---查询条件
    @field varchar(225),        ---查询条件
    @order varchar(100)
)
AS

    declare @sql as nvarchar(4000)
    set @sql = 'DECLARE @Tables TABLE(tid int identity(1,1),nid int);
    set rowcount '+str(@End)+' ;' 
--    declare @test as int
--print @sql
--exec(@sql)

if(@condition<>'')
    begin
        set @sql =  @sql + N' insert into @Tables(nid) SELECT ['+ @idname +'] FROM ['+ @tablename +']   where   '+@condition+'    '+@order  + ';' --order by ['+@idname+']  ' + @order
        --insert into Tables(nid)
        --exec (@sql)
        --print @sql
    end
else
    begin
        set @sql = @sql + N' insert into @Tables(nid) SELECT ['+ @idname +'] FROM ['+ @tablename +']   ' +@order  + ';'    ---order by ['+@idname+']  '+@order
        --insert into Tables(nid) 
        --exec (@sql)
        --print @sql
    end
    
    
        
if(@End<>0)
    begin
        set @sql = @sql + N' select ' +@field+ ' From [' +@tablename+ '] O,@Tables t where O.['+@idname+'] = t.nid And t.tid between '+str(@Start)+' And '+str(@End)+' order by t.tid;'
    end
else
    begin
        set @sql = @sql + N' select ' +@field+ ' From [' +@tablename+ '] O,@Tables t where O.['+@idname+'] = t.nid '+@order
    end

print @sql

--print '2:'+@sql

exec (@sql)
return

 

 

posted on 2010-07-02 18:40  HackerVirus  阅读(362)  评论(0编辑  收藏  举报