SQL Server将标识符传递给存储过程/动态SQL
背景:
SQL Server Management Studio允许定义自己的查询快捷方式(工具>选项>环境>键盘>查询快捷键): 图片来自:http://social.technet.microsoft.com/wiki/contents/articles/3178.how-to-create-query-shortcuts-in-sql-server-management-studio.aspx my_schema.my_table -- highlight it -- press CTRL + 3 and you will get the number of rows in table 它工作正常,但它以基本形式连接查询(据我所知,只有在结尾).查询: SELECT COUNT(*) FROM my_schema.my_table; 尝试#1 现在我想写一些更具体的东西,例如传递/连接表名到以下查询(这只是例子): SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(...) 所以当我写入查询快捷方式: SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(' 我必须使用: my_schema.my_table') -- highlight it -- press CTRL + 3 额外的’)是非常丑陋和不便. 尝试#2: 第二个试验是使用Dynamic-SQL: EXEC dbo.sp_executesql N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)',N'@obj_name SYSNAME', 执行: my_table -- highligt it -- and run
当表名引用[my_table]时也可以.只要对象处于dbo(默认)模式. 问题是当表具有模式时,它将不起作用: EXEC dbo.sp_executesql N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)', 执行: my_schema.my_table [my_schema].[my_table]
当然可以写: EXEC dbo.sp_executesql N'SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@obj_name)',' 并称之为: [my_schema].[my_table]' 但额外的“也是丑陋和不便. 问题: >可以传递值,查询快捷方式窗口,在中间(位置甚至多于一个值)? 备注: >我不搜索SSMS的插件 编辑: 澄清传递标识符到SP而没有“或”: CREATE TABLE dbo.my_table(col INT); GO CREATE PROCEDURE dbo.my_proc @a SYSNAME AS SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@a) GO EXEC dbo.my_proc @a = my_table; EXEC dbo.my_proc @a = dbo.my_table; -- Incorrect syntax near '.'.
解决方法中间有可能传递值,查询快捷方式窗口吗?据我所知,没有办法解决这个问题. 1-B.是否可以传递多个值? 可以使用分隔符来完成字符串值,然后在另一边分割值.可悲的是,没有太多的特殊功能来完成这项工作,因为他们几乎都会引发语法错误.但是,’#’可能是一个明智的选择,因为它已经是临时表中SQL的特殊字符.只要检查你是否还没有使用它的标识符,因为它被SQL允许(很难,它被禁止为第一个字符). 这是一个例子: CREATE PROCEDURE sp_PassingMultipleStringValues @Param1 NVARCHAR(MAX) AS --Here I'm using a XML split,but feel free to use any string split function you already have. DECLARE @xml AS XML,@separator AS VARCHAR(1) SELECT @separator ='#',@xml = CAST('<X>'+ (REPLACE(@Param1,@separator,'</X><X>') +'</X>') AS XML) SELECT N.value('.','VARCHAR(200)') AS value FROM @xml.nodes('X') as T(N) --Do whatever is needed with them 然后在此图像上配置您的快捷方式. (注意最后的空格) 结果: 2.是否可以传递到stored_procedure / dynamic-sql限定标识符,“呢? 你有多个具有相同标识符的模式? 使用检索到的模式,您可以随时为其所需的动态SQL执行动态SQL. SELECT @Param1 = REPLACE(REPLACE(@Param1,'[',''),']','') SELECT TOP 1 @Param1 = [Schema].name + '.' + @Param1 FROM sys.objects AS obj JOIN sys.schemas AS [Schema] ON obj.schema_id = [Schema].schema_id WHERE obj.name = @Param1 SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@Param1) DECLARE @Query NVARCHAR(MAX) = 'SELECT TOP 1 * FROM ' + @Param1 EXEC sp_sqlexec @Query 如果您想要处理具有相同标识符的两个不同模式,那么通过使用答案1-b中解释的方法将模式和标识符作为两个参数来传递仍然是可行的. 一切都在一个例子中 由于这里我们要传递多个标识符并指定其模式,因此需要两个分隔符. CREATE PROCEDURE sp_MultiArgsWithSchema @Param1 NVARCHAR(MAX) AS SELECT @Param1 = REPLACE(REPLACE(@Param1,'') --Here I'm using a XML split,but feel free to use any string split function you already have. DECLARE @xml AS XML,@ArgSeparator AS VARCHAR(2),@SchemaSeparor AS VARCHAR(1) SELECT @ArgSeparator = '##',@SchemaSeparor = '#',@ArgSeparator,'</X><X>') +'</X>') AS XML) IF OBJECT_ID('tempdb..#QualifiedIdentifiers') IS NOT NULL DROP TABLE #QualifiedIdentifiers; --While splitting,we are putting back the dot instead of '#' between schema and name of object SELECT QualifiedIdentifier = REPLACE(N.value('.','VARCHAR(200)'),@SchemaSeparor,'.') INTO #QualifiedIdentifiers FROM @xml.nodes('X') as T(N) SELECT * FROM #QualifiedIdentifiers --From here,use what is inside #QualifiedIdentifiers and Dynamic SQL if need to achieve what is needed DECLARE @QualifiedIdentifier NVARCHAR(500) WHILE EXISTS(SELECT TOP 1 1 FROM #QualifiedIdentifiers) BEGIN SELECT TOP 1 @QualifiedIdentifier = QualifiedIdentifier FROM #QualifiedIdentifiers SELECT * FROM sys.columns WHERE [object_id] = OBJECT_ID(@QualifiedIdentifier) DELETE TOP (1) FROM #QualifiedIdentifiers WHERE QualifiedIdentifier = @QualifiedIdentifier END 用法(请注意,指定模式不是强制性的): 因此,由于不必将分割字符加倍,所以最好是如上所述猜到模式. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |