问题描述
我正在尝试让laravel 7x
与impala/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'))->
但是,我无法获得insert
和update
中的列名。
解决方法
尝试使用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
门面的语句方法:insert
,update
,delete
。
// 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']);