在 SQL Server 中创建存储过程时,您可以引用不存在的表。但是,如果该表确实存在,那么您在过程中引用的任何列都必须存在于该表中(延迟名称解析)。
是否可以指示 SQL Server 推迟过程中引用的所有表的名称解析,而不管它们是否存在?我确实想保持一般语法检查,所以即使有可能,将存储过程定义破解到系统表中也不是一种选择。
我希望我要求这样做可能看起来有点奇怪,所以这里有一些背景:我从用 C# 编写的应用程序自动生成表定义和存储过程,而且我很难更改代码以根据 SQL 需要对更改进行排序他们。我的代码“保证”架构在事务中是一致的,但目前我不能保证在定义引用它们的存储过程之前定义表列。
下面是 C# 创建的 SQL 的规范示例,它“说明”了我要解决的问题。
--Say this table already exists.
CREATE TABLE myTable
(
a NVARCHAR(MAX)
)
GO
--My C# code creates something like this
BEGIN TRAN
GO
--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
SELECT a,b FROM myTable
END
--then the table update
ALTER TABLE myTable
ADD b nvarchar(MAX)
COMMIT TRAN
我可以在 C# 代码中解决这个问题,但我希望我可以在 SQL 中进行一个简单的“魔术”调整。这将为我节省很多时间。
不。
只是打字我感到很内疚,但不,很遗憾。这是我第一次听说这个用例,而且非常有意义。最好在https://feedback.azure.com/forums/908035-sql-server上提交请求,您的孙子将能够做到。;-)
万一您仍然感兴趣,您可以使用一种潜在的解决方法。这是更新后的代码,它将
#deferResolution
临时表引入过程中的每个查询。因为临时表只在运行时存在,所以即使正确的列在myTable
.#deferResolution
由于查询优化器可以证明这WHERE NOT EXISTS
总是评估为真的方式,您甚至会为过程中的每个语句获得相同的执行计划(不引用表)。话虽如此,这是一个可怕的黑客攻击,主要是为了学术兴趣,并且可能存在崩溃的边缘情况。正如 Aaron 所提到的,以正确的顺序进行所有模式更改可能会更好。