错误[37000] [IBM] [CLI驱动程序] CLI0118E无效的SQL语法。 SQLSTATE = 37000

时间:2019-01-14 04:57:31

标签: sql db2 linked-server

我有一个简单的SQL语句查询,该查询作为C#代码中的命令执行。它以DB2为目标。我为服务器/方案创建了变量,如下所示。它引发错误。

private const string DB2Query
            = @"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";

我收到此错误。

  

错误[37000] [IBM] [CLI驱动程序] CLI0118E无效的SQL语法。 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东西吗?有人可以帮忙如何用从{Schema}获取的值替换web.config吗?

1 个答案:

答案 0 :(得分:1)

虽然我不能真正说出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或类成员上运行的原因(我应该想象会产生编译器错误)。

请记住,字符串是不可变的,因此您执行的任何对字符串进行修改的操作都将返回 new 字符串,而不是修改现有字符串一个就位。


无论如何,您当然还需要将查询参数应用于?占位符。注意,在字符串格式化/插值操作中,C#认为是占位符,而DB2认为是查询参数的占位符是两个完全不同的事情,它们在不同的环境中的不同时间发生。 (.NET运行时中的一个,数据库服务器中查询的执行中的一个。)但是,我再次依赖于您的断言,即数据库查询本身可以工作,而我们在此关注的唯一问题是C#字符串占位符。 / p>