设为首页 收藏本站
查看: 785|回复: 0

[经验分享] 动态SQL语句

[复制链接]

尚未签到

发表于 2016-11-8 10:05:06 | 显示全部楼层 |阅读模式
  摘要:有些时候我们需要执行的SQL不是固定不变的,而是需要动态执行的,此时你就需要使用到动态SQL语句,今天我们就一块看一下常见的动态SQL使用方法。
  主要内容

  • 动态执行SQL的两种方式
  • 动态SQL输出参数
  • 执行动态SQL的注意事项
一、动态SQL两种执行方式
EXEC方式
我们知道在执行存储过程时经常用到"EXEC"命令,例如要想执行存储过程"CustOrderHist"就可以使用"EXEC CustOrderHist 'ALFKI'"。其实"EXEC"还有另一种用法就是"EXEC (sql)",通过这种方式我们就可以动态执行sql语句。例如现在我想写一个存储过程,参数就表名和所选择的列,我通过传入这两个参数可以得到指定表的指定列信息,就可以这样来写:
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO-- =============================================-- Author:Kenshin Cui-- Create date: 2010.11.20-- Description:Based on the specified table and column returns the query data-- =============================================CREATE PROCEDURE GetQueryDataByTableNameAndColumns@tableName NVARCHAR(20),@columns NVARCHAR(200)ASBEGINDECLARE @sql NVARCHAR(500)SET @sql='SELECT '+@columns+' FROM '+@tableNameEXEC (@sql)ENDGO
有了上面的存储过程,例如执行" EXECdbo.GetQueryDataByTableNameAndColumns@tableName='Products',@columns='ProductName,UnitPrice'"就可以看到:
DSC0000.gif
在这个存储过程中我们就通过使用"EXEC"来动态执行了SQL。
sp_executesql方式
"sp_executesql"本身是一个存储过程(系统提供),在SQL SERVER 2005及其以上版本才有。通过它我们也可以执行动态SQL,而且通常情况下我们推荐使用这种方法。现在我们就一块看看它的使用方法。假设现在还是实现如上功能我们就可以这么做:
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO-- =============================================-- Author:Kenshin Cui-- Create date: 2010.11.20-- Description:Based on the specified table and column returns the query data-- =============================================CREATE PROCEDURE GetQueryDataByTableNameAndColumns2@tableName NVARCHAR(20),@columns NVARCHAR(200)ASBEGINDECLARE @sql NVARCHAR(500)SET @sql='SELECT '+@columns+' FROM '+@tableNameEXEC sys.sp_executesql @sqlENDGO
执行结果同上面的"EXEC"方式完全相同。
二、带有输出参数的动态SQL
虽然上面两种方式都能够动态执行SQL,但是有些时候你的动态语句中可能还需要带有参数,这时你可能希望在动态执行SQL的同时能够将你的参数返回。例如现在我想要写一个存储过程,功能就是通过传入表名和列名,返回指定列中最大的列值。当然,这是你需要定义一个参数来接收"MAX"值,可是关键问题就是怎么样返回这个值呢?答案就是使用"sp_executesql"方式。"sp_executesql"支持输出参数,这个存储过程除了可以传入一个参数之外(例如我们的例子),还支持传入三个参数(这说明这个存储过程是有两个可选参数的),后者也正可以解决我们的问题。例如要实现之前说的功能就可以这样下:
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO-- =============================================-- Author:Kenshin Cui-- Create date: 2010.11.20-- Description:By specifying the table name and column names to return the maximum value-- =============================================CREATE PROCEDURE GetMaxValueByTableNameAndColumns@tableName NVARCHAR(20),@columnName NVARCHAR(200)ASBEGINDECLARE @sql NVARCHAR(500)DECLARE @outputParamDefine NVARCHAR(100)DECLARE @maxValue NVARCHAR(50)SET @sql='SELECT @maxValue=MAX('+@columnName+') FROM '+@tableNameSET @outputParamDefine='@maxValue NVARCHAR(50) OUTPUT'EXEC sys.sp_executesql @sql,@outputParamDefine,@maxValue OUTPUTSELECT @maxValueENDGO
执行"EXECdbo.GetMaxValueByTableNameAndColumns@tableName='Products',@columnName='ProductID'"后:
DSC0001.gif
三、注意事项
  1.使用"EXEC"实现动态SQL的时候切记在语句前后加上括号。
  2.使用"sp_executesql"实现动态SQL时一定注意语句本身和其参数都必须是"NTEXT"、"NCHAR"、"NVARCHAR"型,而不能是"VARCHAR"等非N型(类型前面没有字母"N"的类型),并且如果是语句的话语句前需要加字母"N"(注意是语句而非变量,变量的话就不需要了;通过在语句前添加"N"的目的也是将其转化为"NTEXT/ NCHAR / NVARCHAR"型);"EXEC"方式可以直接不通过其他变量执行"SQL拼接"(注意是"SQL拼接"而不是"SQL语句",对于不经过拼接的SQL前加上"N"是可以使用"sp_executesql"执行的),而"sp_executesql"不能(即使前面加上"N")。
  下面列出了上面说的几种情况:
  DECLARE @tableName NVARCHAR(20)DECLARE @columns NVARCHAR(200)DECLARE @sql NVARCHAR(500)--当使用sp_executesql执行时不能是VARCHAR(500)SET @tableName='Products'SET @columns='ProductName,UnitPrice'SET @sql=N'SELECT '+@columns+' FROM '+@tableNameEXEC (@sql)--正确!!!EXEC ('SELECT '+@columns+' FROM '+@tableName)--正确!!!EXEC sys.sp_executesql @sql--正确!!!但是如果@sql定义成varchar类型此句就会出错EXEC sys.sp_executesql N'SELECT ProductName,UnitPrice FROM Products'--正确!!!直接执行语句,语句前面必须加“N”EXEC sys.sp_executesql N'SELECT '+@columns+' FROM '+@tableName--错误!!!不能执行sql拼接,即使前面加N

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-297308-1-1.html 上篇帖子: SQL入门 01 下篇帖子: sql server 安装时“无法在COM+目录中安装和配置程序”的解决办法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表