我发现了一些类似的问题但是所有解决方案似乎都与将日期参数传递给sp_executesql有关,这不是我正在做的...
我有一个.NET应用程序,它使用SqlConnection和SqlCommand类连接到SQL数据库。当我使用SQL Server Profiler运行应用程序并监视数据库查询时,我可以看到.NET应用程序正在生成以下代码:
exec sp_executesql N'IF object_id(''tempdb..#ParmsInProc'') IS NOT NULL DROP TABLE #ParmsInProc
SELECT o.name AS ProcName, o.object_id, p.name AS ParamName, p.system_type_id, p.user_type_id
INTO #ParmsInProc
FROM sys.objects o
JOIN sys.parameters p
ON o.object_id = p.object_id
JOIN sys.types t
ON t.system_type_id = p.system_type_id AND t.user_type_id = p.user_type_id
WHERE type_desc = ''SQL_STORED_PROCEDURE'' AND o.name = ''@sp''
SELECT *
FROM #ParmsInProc p
LEFT JOIN (
SELECT *
FROM #ParmsInProc
WHERE system_type_id = 56 AND user_type_id = 56
) ints
ON p.system_type_id = ints.system_type_id AND p.user_type_id = ints.user_type_id',N'@sp nvarchar(14)',@sp=N'sp_myProcedure'
如果我在SSMS中运行该代码,则无法获得任何结果。但是,如果我复制出查询并用实际值替换参数占位符,我会得到
IF object_id('tempdb..#ParmsInProc') IS NOT NULL DROP TABLE #ParmsInProc
SELECT o.name AS ProcName, o.object_id, p.name AS ParamName, p.system_type_id, p.user_type_id
INTO #ParmsInProc
FROM sys.objects o
JOIN sys.parameters p
ON o.object_id = p.object_id
JOIN sys.types t
ON t.system_type_id = p.system_type_id AND t.user_type_id = p.user_type_id
WHERE type_desc = 'SQL_STORED_PROCEDURE' AND o.name = 'sp_myProcedure'
SELECT *
FROM #ParmsInProc p
LEFT JOIN (
SELECT *
FROM #ParmsInProc
WHERE system_type_id = 56 AND user_type_id = 56
) ints
ON p.system_type_id = ints.system_type_id AND p.user_type_id = ints.user_type_id
如果我运行它,我得到一个结果(这是我期望的结果)
导致这种情况的原因是什么?
答案 0 :(得分:1)
如果您尝试“调试”初始查询,您将看到@sp
作为过程名称传递,而不是参数的实际值。
您可以通过编写以下内容来查看:
declare @spname nvarchar(100) = 'my_storedproc';
declare @sql nvarchar(max) = ' IF object_id(''tempdb..#ParmsInProc'') IS NOT NULL DROP TABLE #ParmsInProc
SELECT o.name AS ProcName, o.object_id, p.name AS ParamName, p.system_type_id, p.user_type_id
INTO #ParmsInProc
FROM sys.objects o
JOIN sys.parameters p
ON o.object_id = p.object_id
JOIN sys.types t
ON t.system_type_id = p.system_type_id AND t.user_type_id = p.user_type_id
WHERE type_desc = ''SQL_STORED_PROCEDURE'' AND o.name = ''@sp'';
SELECT *
FROM #ParmsInProc p
LEFT JOIN (
SELECT *
FROM #ParmsInProc
WHERE system_type_id = 56 AND user_type_id = 56
) ints
ON p.system_type_id = ints.system_type_id AND p.user_type_id = ints.user_type_id;'
print @sql
正在生成以下内容:
您需要做的是将其作为参数传递,不需要引号。 我修改了一些你的查询只是为了能够打印它,通过将sql查询存储到变量中,但你当然可以按原样执行它,内联:
declare @spname nvarchar(100) = 'my_storedproc';
declare @sql nvarchar(max) = ' IF object_id(''tempdb..#ParmsInProc'') IS NOT NULL DROP TABLE #ParmsInProc
SELECT o.name AS ProcName, o.object_id, p.name AS ParamName, p.system_type_id, p.user_type_id
INTO #ParmsInProc
FROM sys.objects o
JOIN sys.parameters p
ON o.object_id = p.object_id
JOIN sys.types t
ON t.system_type_id = p.system_type_id AND t.user_type_id = p.user_type_id
WHERE type_desc = ''SQL_STORED_PROCEDURE'' AND o.name = @sp;
SELECT *
FROM #ParmsInProc p
LEFT JOIN (
SELECT *
FROM #ParmsInProc
WHERE system_type_id = 56 AND user_type_id = 56
) ints
ON p.system_type_id = ints.system_type_id AND p.user_type_id = ints.user_type_id;'
print @sql
exec sp_executesql @sql, N'@sp nvarchar(100)', @sp = @spname
这将成功执行,您可以在Messages选项卡下看到打印的sql查询:)