2017-10-05 62 views
1

我发现这几个类似的问题,但所有的解决方案似乎都与传递日期参数以使用sp_executesql这是我做的不算什么......sp_execute SQL给予不同的结果,以原始查询

我有一个使用SqlConnection和SqlCommand类连接到SQL数据库的.NET应用程序。当我运行应用程序并监视使用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

'声明@ sp'和'设置@ sp'初始阶段并尝试。 –

+0

我不认为这是问题,但参数是NVARCHARS,而你的字符串是VARCHAR –

回答

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 

正在生成以下:

enter image description here

你需要做的是什么,只是把它作为一个参数,无需要报价。 我修改了一点查询只是为了能够打印出来,通过存储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 

这将成功执行,你在消息标签下看到打印的sql查询:)

+1

感谢你。就像一对错位的撇号一样简单...... – SEarle1986

+0

不客气! :) –