Laravel查询生成器/如何阻止它添加[括号]?

问题描述

我正在尝试让laravel 7ximpala/kudu提供的cloudera一起使用。我有ODBC connection可以很好地连接,如果您运行原始SQL查询,它也可以正常工作。

数据库连接条目:

'impala_connect' => [
    'driver' => 'sqlsrv','odbc' => true,'odbc_datasource_name'=> 'cloudera_odbc_connection','host' => '','port' => '','database' => '','username' => '','password' => '','pooling'  => false,],

原始查询工作正常:

DB::connection('impala_connect')->raw("insert into test1 values(4,'z')");
DB::connection('impala_connect')->select(DB::raw('select * from test1'));

查询生成器失败:

但是,当我使用laravel的查询构建器来运行某些查询时,它们都会失败,并带有laravel自己添加的括号。

DB::connection('impala_connect')->table('test1')->get(['id','val']);

//or
DB::connection('impala_connect')->table('test1')->insert([
  'id'=> 5,'val'=> 'z'
]);

这是我得到的错误

sqlSTATE: General error: 0 [Cloudera][ImpalaODBC] (110) Error while executing a query in Impala : ParseException: Syntax error in line 1: select [id],[val] from [test1] ^ 
Encountered: COMMA Expected: CASE,CAST,DEFAULT,EXISTS,FALSE,IF,INTERVAL,LEFT,NOT,NULL,REPLACE,RIGHT,TruncATE,TRUE,IDENTIFIER 
CAUSED BY: Exception: Syntax error (sqlPrepare[0] at pdo_odbc\odbc_driver.c:206) (sql: select [id],[val] from [test1])

您可以看到实际查询变成了每个项目的括号,而那是失败的地方。

那么如何使laravel不包裹括号?!


编辑:

我确实弄清楚了如何至少在没有括号的情况下获得表名。

->table(db::raw('test1'))->

但是,我无法获得insertupdate中的列名。

解决方法

尝试使用select,然后使用get

DB::connection('impala_connect')->table('test1')->select('id','val')->get();
,

您正在使用SQL Server驱动程序。 'driver' => 'sqlsrv' 我对impala一无所知,但它首先与SQL Server的语法兼容吗?

用方括号([id])包裹的列通常是关键字或包含特殊字符或空格。在使用sqlsrv驱动程序时,Laravel默认将所有内容括在方括号中。这是常见的行为。

使用mysql驱动程序时,它通过将所有内容包装在反引号``中来执行相同的操作。

这是使用查询生成器使用不同的驱动程序创建简单的SQL查询SELECT id,name FROM table的结果。如您所见,它将每个选定的列和表名视为每个驱动程序中都有特殊字符。这样做是为了保持一致性。

>>> DB::connection('mysql')->table('table')->select('id','name')->toSql()
=> "select `id`,`name` from `table`"
>>> DB::connection('pgsql')->table('table')->select('id','name')->toSql()
=> "select "id","name" from "table""
>>> DB::connection('sqlite')->table('table')->select('id',"name" from "table""
>>> DB::connection('sqlsrv')->table('table')->select('id','name')->toSql()
=> "select [id],[name] from [table]"

我得出结论,sqlsrv驱动程序与Impala的语法不兼容。包装是通过位于wrapValue中的函数vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\SqlServerGrammar.php完成的。

完全不建议使用,但是如果没有其他选择,则可以对其进行编辑。

如果您不介意原始查询,另一种选择是简单地使用DB门面的语句方法:insertupdatedelete

// returns bool
DB::insert('insert into users (id,name) values (?,?)',[1,'Dayle']);
// returns int (number of rows affected)
DB::update('update users set name = ? where id = ?',['Dayle',1]);
DB::delete('delete from users where name = ?',['Dayle']);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...