包含Dynamic Sql和Temp表 的问题 存储proc是诸如SSRS和ORM生成器(如Linq2SQL和EF逆向工程工具)之类的向导的祸根。
这是因为在运行PROC之前
SET FMTONLYON;(或最近使用
sp_describe_first_result_set)的工具是为了导出PROC生成的结果集架构,以便可以生成ReportViewer
UI的映射。但是,既
FMTonLY ON没有
sp_describe_first_result执行PROC ,也没有实际执行。
例如,该工具将执行以下操作:
SET FMTonLY ON;EXEC dbo.MyProc NULL;
一些解决方法:
- 手动编辑RDL / RDLC文件以插入实际结果集的列名称和类型。
- 临时删除实际proc并将其替换为一个,它将返回零个或更多行的数据集,其中包含实际proc返回的实际数据类型和列名,并运行向导,然后还原真实proc。
- 临时添加
SET FMTonLY OFF;
为PROC的第一行-这将强制执行PROC。完成后还原原始的PROC(尽管请注意,由于该工具传递的null或哑元参数,您的proc可能会失败)。此外,FMTONLY
在被弃用 - 在proc的开始处,添加一个伪语句,该语句返回结果集的实际模式,并包装在一个永远不会执行的条件分支中。
这是最近一次黑客攻击的示例:
CREATE PROCEDURE [dbo].[Get_Details_by_Type] @isArchived varchar(10), @Type varchar(50)ASBEGIN -- For FMTonLY ON tools only IF 1 = 2 BEGIN -- These are the actual column names and types returned by the real proc SELECT CAST('' AS NVARCHAr(20)) AS Col1, CAST(0 AS DECIMAL(5,3)) AS Col2, ... END;-- Rest of the actual PROC goes hereFMTonLY ON/
sp_describe_first_result_set由虚拟条件欺骗,并采用从未执行的分支中的架构。
顺便说一句,出于您自己的理智考虑,我建议您不要
SELECT *在PROC中使用-而是明确列出从中返回的所有实际列名
Orders
最后,只需确保您没有
SET FMTonLY ON;在proc中包含该语句(从上面的代码中即可!)
END - ProcGO **SET FMTonLY ON; ** This isn't part of the Proc!



