错误 [37000] [IBM][CLI 驱动程序] CLI0118E 无效的 SQL 语法。 SQL状态=37000
ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000
我有一个简单的 SQL 语句查询,它作为 C# 代码中的命令执行。它以 DB2 为目标。我为 server/schemas 创建了如下变量。它抛出错误。
private const string DB2Query
= @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
我收到这个错误。
ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000
但是,从 SQL 执行时,我没有收到如下错误:
SELECT Name as Name
FROM MyServer..FOR3.Application
WHERE ID = 'MOM'
为了支持这一点,我也尝试在代码中执行类似下面的操作,但仍然会抛出不同的错误。
private const string DB2Query
= @"SELECT Name as Name FROM {ServerName}..{Schema}.Application WHERE ID = ?";
它在这行代码上抛出错误:
DataApplicationBlockHelper<string>.Get(db, dbCommand, Obj);
更新
我找到了罪魁祸首。它不会替换 {Schema}
占位符。当我实际从查询中删除它并放置模式名称时,它就像一个魅力。我相信这是一个 .net 的东西?有人可以帮助如何用从 web.config
中获取的值替换 {Schema}
吗?
虽然我不能真正说明 DB2 查询本身的语法,所以我将依赖您的断言,即查询 本身 应该有效...
您在 C# 中拥有的只是一个字符串,仅此而已:
private const string DB2Query = @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
请注意,在此字符串定义中不需要 @
运算符,因此让我们简化一下:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
虽然此字符串 直观地 显示有一个可以用值替换的占位符,但如果没有代码可以在任何地方执行此操作,那么它就不会发生。为此,您有几种选择。例如,您可以使用 string.Format()
理解的占位符:
private const string DB2Query = "SELECT Name as Name FROM {0}.Application WHERE ID = ?";
然后在某处的某个方法中,当您想使用该字符串时,将格式值应用于它:
var sql = string.Format(DB2Query, someVariable);
在这种情况下,someVariable
(甚至不需要是变量,可以是字符串文字)将用于替换字符串中的占位符。
或者,如果您想保留命名占位符,您可以手动替换它:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
以及稍后在方法中:
var sql = DB2Query.Replace("{Schema}", someVariable);
这会明显地完成同样的事情,也许性能差异非常小。
您还可以通过使用字符串插值的最新语言功能来利用这两种方法。这将使用 $
运算符直接应用格式占位符。我不认为你可以在 const
中使用它,它更适用于局部变量。像这样:
var sql = $"SELECT Name as Name FROM {someVariable}.Application WHERE ID = ?";
这仍然会执行相同的替换,将 someVariable
放在占位符所在的位置,它只是使用了比调用 string.Format()
更简洁的语法。关于这种语法需要注意的一件事是,它使它看起来更像是这种插值直接发生在字符串上。它仍然是幕后的多步骤过程,这就是为什么它可能根本无法在 const
或 class 成员上工作(我应该想象会产生编译器错误)。
请记住,字符串是 不可变的,因此您执行的任何 修改 字符串的操作都将返回 新的 字符串而不是修改现有的字符串。
无论如何,您当然还需要为 ?
占位符应用查询参数。请注意,C# 认为是字符串 formatting/interpolating 操作中的占位符和 DB2 认为是查询参数的占位符是两种完全不同的事情,它们在不同环境中的不同时间发生。 (一个在 .NET 运行时中,一个在数据库服务器的查询执行中。)但是,我再次依赖于您关于数据库查询本身有效的断言,我们在这里关注的唯一问题是 C# 字符串占位符。
我有一个简单的 SQL 语句查询,它作为 C# 代码中的命令执行。它以 DB2 为目标。我为 server/schemas 创建了如下变量。它抛出错误。
private const string DB2Query
= @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
我收到这个错误。
ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000
但是,从 SQL 执行时,我没有收到如下错误:
SELECT Name as Name
FROM MyServer..FOR3.Application
WHERE ID = 'MOM'
为了支持这一点,我也尝试在代码中执行类似下面的操作,但仍然会抛出不同的错误。
private const string DB2Query
= @"SELECT Name as Name FROM {ServerName}..{Schema}.Application WHERE ID = ?";
它在这行代码上抛出错误:
DataApplicationBlockHelper<string>.Get(db, dbCommand, Obj);
更新
我找到了罪魁祸首。它不会替换 {Schema}
占位符。当我实际从查询中删除它并放置模式名称时,它就像一个魅力。我相信这是一个 .net 的东西?有人可以帮助如何用从 web.config
中获取的值替换 {Schema}
吗?
虽然我不能真正说明 DB2 查询本身的语法,所以我将依赖您的断言,即查询 本身 应该有效...
您在 C# 中拥有的只是一个字符串,仅此而已:
private const string DB2Query = @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
请注意,在此字符串定义中不需要 @
运算符,因此让我们简化一下:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
虽然此字符串 直观地 显示有一个可以用值替换的占位符,但如果没有代码可以在任何地方执行此操作,那么它就不会发生。为此,您有几种选择。例如,您可以使用 string.Format()
理解的占位符:
private const string DB2Query = "SELECT Name as Name FROM {0}.Application WHERE ID = ?";
然后在某处的某个方法中,当您想使用该字符串时,将格式值应用于它:
var sql = string.Format(DB2Query, someVariable);
在这种情况下,someVariable
(甚至不需要是变量,可以是字符串文字)将用于替换字符串中的占位符。
或者,如果您想保留命名占位符,您可以手动替换它:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
以及稍后在方法中:
var sql = DB2Query.Replace("{Schema}", someVariable);
这会明显地完成同样的事情,也许性能差异非常小。
您还可以通过使用字符串插值的最新语言功能来利用这两种方法。这将使用 $
运算符直接应用格式占位符。我不认为你可以在 const
中使用它,它更适用于局部变量。像这样:
var sql = $"SELECT Name as Name FROM {someVariable}.Application WHERE ID = ?";
这仍然会执行相同的替换,将 someVariable
放在占位符所在的位置,它只是使用了比调用 string.Format()
更简洁的语法。关于这种语法需要注意的一件事是,它使它看起来更像是这种插值直接发生在字符串上。它仍然是幕后的多步骤过程,这就是为什么它可能根本无法在 const
或 class 成员上工作(我应该想象会产生编译器错误)。
请记住,字符串是 不可变的,因此您执行的任何 修改 字符串的操作都将返回 新的 字符串而不是修改现有的字符串。
无论如何,您当然还需要为 ?
占位符应用查询参数。请注意,C# 认为是字符串 formatting/interpolating 操作中的占位符和 DB2 认为是查询参数的占位符是两种完全不同的事情,它们在不同环境中的不同时间发生。 (一个在 .NET 运行时中,一个在数据库服务器的查询执行中。)但是,我再次依赖于您关于数据库查询本身有效的断言,我们在这里关注的唯一问题是 C# 字符串占位符。