0 sql-server stored-procedures sql-server-2014
今天我注意到在 SQL Server 2014 中创建存储过程的过程中出现了一个奇怪的行为。下面是我的测试过程。请解释为什么 SQL Server 不允许用第一个SELECT
编译而允许用第二个编译。
CREATE PROCEDURE [dbo].[test]
AS
BEGIN
SET NOCOUNT ON;
IF 1=0 -- this will never occur
BEGIN
select x from Table -- TABLE EXIST BUT COLUMN NOT - STORED PROCEDURE IS NOT CREATED
--Msg 207, Level 16, State 1, Procedure test, Line 25
--Invalid column name 'x'.
-- But if i change
select x from TableWhichNotExistInDatabase -- This table not exist in database, but stored procedure has been created without any problems and I can exec it without errors ( because of 1=0 in if )
END
ELSE
SELECT ''
END
Run Code Online (Sandbox Code Playgroud)
在我的实际过程中,我正在创建具有各种模式的临时表(从作为参数传递的 XML)。接下来我尝试验证存储过程中的一些数据。验证块由 IF 语句控制。
临时表的创建和存储过程调用由动态创建的过程执行。
我认为问题出在执行计划或类似的创建过程中的某个地方。如果数据库中不存在该表,则 SQL Server 允许在表不存在时创建存储过程。但是,当表存在时,存储过程的创建失败,因为架构无效 - 没有列。
我正在寻找一种禁用模式检查但没有任何成功的解决方案。
关于如何绕过此限制有什么想法吗?
您遇到的现象称为Deferred Name Resolution。
创建存储过程时,会解析过程中的语句以确保语法准确性。如果在过程定义中遇到语法错误,则会返回错误并且不会创建存储过程。如果语句在语法上正确,则存储过程的文本存储在 sys.sql_modules 目录视图中。
当第一次执行存储过程时,查询处理器从 sys.sql_modules 目录视图中读取存储过程的文本,并检查该过程使用的对象的名称是否存在。这个过程称为延迟名称解析,因为存储过程引用的表对象在创建存储过程时不需要存在,而只在执行时才存在。
> 延迟名称解析只能在您引用不存在的表对象时使用。所有其他对象在创建存储过程时必须存在。例如,当您在存储过程中引用现有表时,您不能列出该表不存在的列。
我知道解决这个问题的唯一方法是使用动态 SQL。
归档时间: |
|
查看次数: |
490 次 |
最近记录: |