sqlserver语法的表格式错误

时间:2018-10-02 10:34:58

标签: php sql-server laravel sqlsrv

我正在使用Laravel查询生成器从sqlsrv数据库中获取一些数据。我要查找的表是dbo.[Reukema Blocq Maneschijn BV$Time Slot (Weighbridge)]。不是我的选择。该数据库是由另一家公司开发的。

执行查询时,我不断收到General error: 20018 Invalid object name错误。我仔细检查了拼写错误的名称,但找不到。

我发现在编译查询时出现问题。这是我的代码来测试问题:

$query = $connection->query()
    ->from('Reukema Blocq Maneschijn BV$Time Slot (Weighbridge)')
    ->toSql()

转储$query时,我得到以下信息:

string(67) "select * from [Reukema Blocq Maneschijn BV$Time Slot ](Weighbridge)"

]在这里的位置错误。

即使使用raw()助手,此问题仍然存在:

$query = $connection->query()
    ->from($connection->raw('dbo.[Reukema Blocq Maneschijn BV$Time Slot (Weighbridge)]'))
    ->toSql()

即使在最后一个示例中,]也从字符串的末尾移到(的正前方。

这是为什么?我是否缺少编译sqlsrv查询的重要规则/机制?

以下代码可以正常工作。这对我来说更奇怪:

$connection->select('select [Time Slot] as [id] from [Reukema Blocq Maneschijn BV$Time Slot (Weighbridge)]');

因此,我认为SqlServerGrammar@compileFrom方法中存在问题。 Laravel为什么这样编译它?

2 个答案:

答案 0 :(得分:0)

我个人强烈建议您更改对象的名称;那是一个糟糕的选择。如果您无法执行此操作,则可以创建一个更“有用”的同义词。例如:

CREATE SYNONYM dbo.WeighbridgeSlot FOR dbo.[Reukema Blocq Maneschijn BV$Time Slot (Weighbridge)];

然后在您的应用程序代码中调用同义词:

$query = $connection->query()
    ->from('WeighbridgeSlot')
    ->toSql()

答案 1 :(得分:0)

使用xDebug做一些测试之后。我发现了问题。这是Illuminate\Database\Query\Grammars\SqlServerGrammer@wrapTableValuedFunction方法。

Laravel错误地将我的表名视为表值函数。这就是查询的编译无法正常工作的原因。

我现在使用的修复程序有点脏:

$query = $connection->query()
    ->from('Reukema Blocq Maneschijn BV$Time Slot (Weighbridge) as time_slots')
    ->toSql()

通过在我的from方法的末尾添加一个别名,可以以另一种方式来编译表名。这样可以防止对表值函数进行编译。

我不确定是否应该将其报告为错误。或者,如果我必须使用的表名是无效的。

编辑:我报告了该错误并创建了修复程序。您可以找到问题(和PR)here