我有一个SQL Server 2008,其表格就像一个哈希映射。基本上,有三列(id, key, val
),我需要拉出其他列a, b, c, d, e
。
目的是基本上选择我需要查询数据的数据库。与此问题类似Using the correct database
我使用强力方法获取SQL。我只是想以更好,更有效的方式做到这一点
这是我想要开始工作的SQL:
CREATE PROCEDURE [dbo].[me]
@partitionName VARCHAR(64),
@id INT
AS
BEGIN
SET NOCOUNT ON
SET ROWCOUNT 0
DECLARE @table as varchar(128)
DECLARE @sql as nvarchar(4000)
DECLARE @params as nvarchar(4000)
DECLARE @s_key as varchar(64)
DECLARE @paramDefinition as nvarchar(4000)
DECLARE @a INT
DECLARE @b VARCHAR(32)
DECLARE @c VARCHAR(32)
DECLARE @d VARCHAR(32)
DECLARE @e VARCHAR(32)
SET @table = @partitionName + '.dbo.hash_table'
SET @sql =
N'SELECT ' +
N' @a = MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END),
@b = MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END),
@c = MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END),
@d = MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END),
@e = MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END)
FROM ' + @table +
N'WHERE id = ' + CONVERT(VARCHAR(3), @id)
EXEC sp_executesql @sql
但是,这会产生以下错误
必须声明标量变量“@a”
我有一种感觉,我需要做一些事情,例如将@paramsDefinition
传递给sp_executesql
但到目前为止,这些都失败了
SET @paramDefinition = '@a INT OUTPUT, '
+ ' @b varchar(32) OUTPUT, '
+ ' @c varchar(32) OUTPUT, '
+ ' @d varchar(32) OUTPUT,'
+ ' @r varchar(32) OUTPUT'
...
EXEC sp_executesql @sql, @paramDefintions
我得到了
'='附近的语法不正确。
这是蛮力方法(有效但击中DB 5次)
SET @key = 'a'
SET @sql =
N' SELECT @a = val FROM ' + @table +
N' WHERE key = ' + quotename(@key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), @nid)
EXEC sp_executesql @sql, N'@a varchar(32) OUTPUT', @a = @a OUTPUT
SET @key = 'b'
SET @sql =
N' SELECT @b = val FROM ' + @table +
N' WHERE key = ' + quotename(@key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), @id)
EXEC sp_executesql @sql, N'@b varchar(32) OUTPUT', @b = @b OUTPUT
SET @key = 'c'
SET @sql =
N' SELECT @c = val FROM ' + @table +
N' WHERE key = ' + quotename(@key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), @id)
EXEC sp_executesql @sql, N'@c varchar(32) OUTPUT', @c = @c OUTPUT
SET @key = 'd'
SET @sql =
N' SELECT @d = val FROM ' + @table +
N' WHERE key = ' + quotename(@key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), @id)
EXEC sp_executesql @sql, N'@d varchar(32) OUTPUT', @d = @d OUTPUT
SET @key = 'e'
SET @sql =
N' SELECT @e = val FROM ' + @table +
N' WHERE key = ' + quotename(@key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), @id)
EXEC sp_executesql @sql, N'@e varchar(32) OUTPUT', @e = @e OUTPUT
SELECT @a as [a], @b as [b], @c as [c], @d as [d], @r as [r]
答案 0 :(得分:1)
您可以尝试使用这样的临时表:
CREATE PROCEDURE [dbo].[me]
@partitionName VARCHAR(64),
@id INT
AS
BEGIN
SET NOCOUNT ON
SET ROWCOUNT 0
DECLARE @table as varchar(128)
DECLARE @sql as nvarchar(4000)
DECLARE @params as nvarchar(4000)
DECLARE @s_key as varchar(64)
DECLARE @paramDefinition as nvarchar(4000)
DECLARE @a INT
DECLARE @b VARCHAR(32)
DECLARE @c VARCHAR(32)
DECLARE @d VARCHAR(32)
DECLARE @e VARCHAR(32)
SET @table = @partitionName + '.dbo.hash_table'
CREATE TABLE #tmp (code varchar(50))
SET @sql =
N'SELECT ' +
N' MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END) as [a],
MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END) as [b],
MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END) as [c],
MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END) as [d],
MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END) as [e]
FROM ' + @table +
N'WHERE id = ' + CONVERT(VARCHAR(3), @id)
INSERT INTO #tmp (code)
EXEC sp_executesql @sql
SELECT * from #tmp
希望它有所帮助。
答案 1 :(得分:0)
试试这个......
动态SQL有自己的作用域,存储过程中的变量对动态sql是不可见的,你需要将这些变量声明为sp_execuetsql的第二个参数,因为你要在这些变量中恢复值,你需要将这些变量传递给sp_executesql时,请使用关键字OUTPUT
,如下所示
CREATE PROCEDURE [dbo].[me]
@partitionName SYSNAME,
@id INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @table as varchar(128)
DECLARE @sql as nvarchar(4000)
DECLARE @params as nvarchar(4000)
DECLARE @s_key as varchar(64)
DECLARE @paramDefinition as nvarchar(4000)
DECLARE @a INT
DECLARE @b VARCHAR(32)
DECLARE @c VARCHAR(32)
DECLARE @d VARCHAR(32)
DECLARE @e VARCHAR(32)
SET @table = @partitionName + 'hash_table'
SET @sql = N'SELECT ' +
N' @a = MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END),
@b = MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END),
@c = MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END),
@d = MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END),
@e = MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END)
FROM dbo.' + QUOTENAME(@table) +
N' WHERE id = @id)'
EXEC sp_executesql @sql
,N'@a INT OUTPUT, @b VARCHAR(32) OUTPUT,@b VARCHAR(32) OUTPUT,@c VARCHAR(32) OUTPUT,
@d VARCHAR(32) OUTPUT,@e VARCHAR(32) OUTPUT, @id INT'
,@a OUTPUT
,@b OUTPUT
,@c OUTPUT
,@d OUTPUT
,@e OUTPUT
,@id
END