Sql 对具有';%的字符串使用格式设置';已经签字了吗

Sql 对具有';%的字符串使用格式设置';已经签字了吗,sql,delphi,delphi-10-seattle,Sql,Delphi,Delphi 10 Seattle,我有一个字符串,它存储我的SQL代码,它看起来像这样: 'SELECT * FROM myTable WHERE myField LIKE '%2015' AND myOtherField = %d' 第一个问题:如何仅在myOtherField上使用?下面的代码似乎没有忽略第一个%符号: MyQuery.SQL.Add(Format(myString, myNumber)); 第二个问题:当我的SQL需要第一个“%”符号,但我也想格式化日期时,如何使用格式?遗憾的是,下面的代码也不起作用

我有一个
字符串
,它存储我的SQL代码,它看起来像这样:

'SELECT * FROM myTable WHERE myField LIKE '%2015' AND myOtherField = %d'
第一个问题:如何仅在
myOtherField
上使用?下面的代码似乎没有忽略第一个%符号:

MyQuery.SQL.Add(Format(myString, myNumber));
第二个问题:当我的SQL需要第一个“%”符号,但我也想格式化日期时,如何使用格式?遗憾的是,下面的代码也不起作用

'SELECT * FROM myTable WHERE myField LIKE '%%d' AND myOtherField = %d'

在要保留的%符号之前添加额外的%

像这样:

  Caption := Format('SELECT * FROM myTable WHERE myField LIKE ''%%2015'' AND myOtherField = %d', [4711]);
和问题2的相同解决方案:

  Caption := Format('SELECT * FROM myTable WHERE myField LIKE ''%%%d'' AND myOtherField = %d', [4711, 4712]);

在要保留的%符号之前添加额外的%

像这样:

  Caption := Format('SELECT * FROM myTable WHERE myField LIKE ''%%2015'' AND myOtherField = %d', [4711]);
和问题2的相同解决方案:

  Caption := Format('SELECT * FROM myTable WHERE myField LIKE ''%%%d'' AND myOtherField = %d', [4711, 4712]);
我建议这应该是所有问题的样板解决方案;它只需要很少的额外工作,而且比摆弄引号和转义字符更具可读性

考虑到这个问题,这并不是说公认的答案是错误的

我建议这应该是所有问题的样板解决方案;它只需要很少的额外工作,而且比摆弄引号和转义字符更具可读性



这并不是说给出的答案是错误的。

@Martyn将这里的字符串与代码中的字符串进行比较different@DavidHeffernan:是的,我知道,我只是想说OP显然已经尝试了%%(但可能是因为没有避开引号而绊倒了)。在我描述的第二段代码中,已经有一个“%”,并且代码是我尝试使用的,但不起作用。这就是我一直在寻找的答案,添加一个额外的%可以解决这个问题。谢谢@我会的,但我还得再等一分钟@雷耶斯。我同意你应该接受这个答案,因为它直接正确地回答了你提出的问题。然而,正如其他人所注意到的,请记住,尽管上面的方法现在可以工作,但它仍然是构建SQL查询的错误方法。Hugh的回答演示了如何使用参数来构建查询-这就是您实际应该如何解决问题的方法。@Martyn比较此处的字符串,以及代码中的字符串different@DavidHeffernan:是的,我知道,我只是想说OP显然已经尝试了%%(但可能是因为没有避开引号而绊倒了)。在我描述的第二段代码中,已经有一个“%”,该代码是我尝试使用的代码,但不起作用。这就是我一直在寻找的答案,添加一个额外的%可以解决这个问题。谢谢@我会的,但我还得再等一分钟@雷耶斯。我同意你应该接受这个答案,因为它直接正确地回答了你提出的问题。然而,正如其他人所注意到的,请记住,尽管上面的方法现在可以工作,但它仍然是构建SQL查询的错误方法。Hugh的回答演示了如何使用参数来构建查询-这就是您实际应该如何解决问题的方法。停止这样做,使用参数。您在这里是安全的,但是对于
格式
,您离SQL注入只有一小步之遥,您的问题的答案可以在文档中找到:@DavidHeffernan更不用说参数化查询的性能更高,通常更为显著。对于堆栈溢出,我们肯定需要一个“不要这样做!”标志。这是一个合法但错误的问题-不要对SQL中可能受污染的值使用字符串组合(我知道%d基本上是安全的,但模式仍然有问题。)停止此操作并使用参数。您在这里是安全的,但是对于
格式
,您离SQL注入只有一小步之遥,您的问题的答案可以在文档中找到:@DavidHeffernan更不用说参数化查询的性能更高,通常更为显著。对于堆栈溢出,我们肯定需要一个“不要这样做!”标志。这是一个合法但错误的问题-不要对SQL中可能受污染的值使用字符串组合(我知道%d基本上是安全的,但模式仍然有问题。)或者,您也可以按名称索引参数。如果以后更改查询并且参数的顺序发生更改,这将非常有用。ie:
MyQuery.Parameters.ParamByName('MyField')。值:='%2015'
J。。。是正确的-
ParamByName
在sql字符串与设置参数值的代码分离时尤其常见。性能受到的影响很小,但更安全。事实上,这取决于用例。一般来说,在性能成为一个问题之前,我会先为清晰性和可维护性编写代码。@J。。。我不确定我是否100%同意在您的编辑中添加
BeginUpdate
EndUpdate
。这不会使问题变得模糊吗?为什么不直接赋值给MyQuery.Sql.Text而不是.Add()呢?或者,您也可以按名称索引参数。如果以后更改查询并且参数的顺序发生更改,这将非常有用。ie:
MyQuery.Parameters.ParamByName('MyField')。值:='%2015'
J。。。是正确的-
ParamByName
在sql字符串与设置参数值的代码分离时尤其常见。性能受到的影响很小,但更安全。事实上,这取决于用例。一般来说,在性能成为一个问题之前,我会先为清晰性和可维护性编写代码。@J。。。我不确定我是否100%同意在您的编辑中添加
BeginUpdate
EndUpdate
。这不会让问题变得有点模糊吗?为什么不直接赋值给MyQuery.Sql.Text而不是.Add()呢?