为什么一个if语句下的查询是false运行?
Why is a query under a IF statement that is false running?
我有一个应用程序对 SQL 查询使用大量字符串插值。我知道这是一个 SQL 注入威胁,这是客户和我们都知道的事情,希望我们可以专注于下一次重大重构。我这么说是为了理解来自 GUI 的 {Root Container.property}
东西。
我有这个问题
IF ({Root Container.UserSelectedProduct}=1)
begin
DECLARE @TestNumbers {Root Container.SQLProductType};
INSERT INTO @TestNumbers SELECT * FROM {Root Container.DBTable};
SELECT *
FROM {Root Container.SQLProductFunction} (@TestNumbers)
WHERE [ID] = {Root Container.Level};
end
else
Select 0
在用户select使用产品之前它看起来像这样
IF (0=1)
BEGIN
DECLARE @TestNumbers myDataType;
INSERT INTO @TestNumbers SELECT * FROM [MySchema].[TheWrongTable];
SELECT * FROM [dbo].[myfunction] (@TestNumbers)
WHERE [ID] = 1;
END
ELSE
SELECT 0
这是给我的错误:
Column name or number of supplied values does not match table definition.
我知道为什么会出现此错误,我正在 select 使用的 table 不是针对该数据类型制作的。
但是,为什么当我有 IF (0=1)
时它甚至试图 运行 第一个 IF 子句 - 为什么这部分不只是被跳过而 SELECT 0
只是 运行?我原以为它应该是这样工作的,但我不断收到有关列 name/number 与 table 定义不匹配的错误。当用户使用 select 一个产品,而我得到 IF (1=1)
并且我有合适的 table/function/datatype,一切都会顺利进行。我只是不知道为什么它会在 IF(1=0) 之前抛出一个错误。为什么这个 happen/how 我可以得到我的预期行为,即我的第一个 IF 语句下 BEGIN\END
中的所有内容都不会 运行 除非表达式为真。
T-SQL 没有解释。无论运行时条件如何,它都必须有意义。事实上,它甚至不会短路。您的代码无效,它无法访问并不重要 - T-SQL 不会仅仅因为它可以被消除而忽略一段无效代码,这是错误的常见来源(例如,在 C++ 中模板很常见)。
只要确保您在没有选择产品的情况下仍然有效SQL;如果必须,请使用错误的 table(或助手 table)。
答案很简单: SQL代码在被执行之前完全由服务器编译,所以这基本上是编译错误。这有点像尝试在 C#
中编译以下内容
if(someBoolWhichIsFalse)
intValue = "hello";
根本无效。
运行时代码还没有执行,还在解析和词法分析阶段。没有任何内容被跳过,它只需要是完全有效的代码,而不考虑运行时条件。
这发生在每个范围内,即在每次调用过程或临时批处理时,该代码必须是可编译的。
我有一个应用程序对 SQL 查询使用大量字符串插值。我知道这是一个 SQL 注入威胁,这是客户和我们都知道的事情,希望我们可以专注于下一次重大重构。我这么说是为了理解来自 GUI 的 {Root Container.property}
东西。
我有这个问题
IF ({Root Container.UserSelectedProduct}=1)
begin
DECLARE @TestNumbers {Root Container.SQLProductType};
INSERT INTO @TestNumbers SELECT * FROM {Root Container.DBTable};
SELECT *
FROM {Root Container.SQLProductFunction} (@TestNumbers)
WHERE [ID] = {Root Container.Level};
end
else
Select 0
在用户select使用产品之前它看起来像这样
IF (0=1)
BEGIN
DECLARE @TestNumbers myDataType;
INSERT INTO @TestNumbers SELECT * FROM [MySchema].[TheWrongTable];
SELECT * FROM [dbo].[myfunction] (@TestNumbers)
WHERE [ID] = 1;
END
ELSE
SELECT 0
这是给我的错误:
Column name or number of supplied values does not match table definition.
我知道为什么会出现此错误,我正在 select 使用的 table 不是针对该数据类型制作的。
但是,为什么当我有 IF (0=1)
时它甚至试图 运行 第一个 IF 子句 - 为什么这部分不只是被跳过而 SELECT 0
只是 运行?我原以为它应该是这样工作的,但我不断收到有关列 name/number 与 table 定义不匹配的错误。当用户使用 select 一个产品,而我得到 IF (1=1)
并且我有合适的 table/function/datatype,一切都会顺利进行。我只是不知道为什么它会在 IF(1=0) 之前抛出一个错误。为什么这个 happen/how 我可以得到我的预期行为,即我的第一个 IF 语句下 BEGIN\END
中的所有内容都不会 运行 除非表达式为真。
T-SQL 没有解释。无论运行时条件如何,它都必须有意义。事实上,它甚至不会短路。您的代码无效,它无法访问并不重要 - T-SQL 不会仅仅因为它可以被消除而忽略一段无效代码,这是错误的常见来源(例如,在 C++ 中模板很常见)。
只要确保您在没有选择产品的情况下仍然有效SQL;如果必须,请使用错误的 table(或助手 table)。
答案很简单: SQL代码在被执行之前完全由服务器编译,所以这基本上是编译错误。这有点像尝试在 C#
中编译以下内容if(someBoolWhichIsFalse)
intValue = "hello";
根本无效。
运行时代码还没有执行,还在解析和词法分析阶段。没有任何内容被跳过,它只需要是完全有效的代码,而不考虑运行时条件。
这发生在每个范围内,即在每次调用过程或临时批处理时,该代码必须是可编译的。