OS: CentOS 7
DB: MSSQL 2000
Larvel: 8
PHP: 7.4.26
各位好,我要使用 Laravel Eloquent 連結 MSSQL 2000,2000 太舊了用現行的 driver 連不到,爬了文建議使用 odbc + FreeTDS,於是我參考了這篇文章,在 CentOS 順利的用該網站的範例連結到了 MSSQL,中文也沒有問題。
<?php
$host = '{IP}';
$port = '1433';
$dbname = '{DATABASE}';
$username = '{USERNAME}';
$password = '{PASSWORD}';
try {
$dsn ='odbc:Driver=FreeTDS;Server=' . $host . ';Port=' . $port . ';Database=' . $dbname . ';UID=' . $username . ';PWD=' . $password . ';clientcharset=UTF-8';
$dbConn = new PDO($dsn);
$stmt = $dbConn->query("SELECT TOP 2 t.*
FROM {DATABASE}.dbo.{TABLE} t
WHERE CREATOR = '{SOMEONE}'
ORDER BY CREATE_DATE DESC");
$row = $stmt->fetchAll();
echo '<pre>';
var_dump($row);
echo '</pre>';
} catch (PDOException $e) {
echo $e->getMessage();
}
然後我去了 packagist 用 Laravel odbc 找了幾個套件來嘗試:
Laravel 已經順利連到了,如果不下任何條件可以撈到資料,但下了一些基本的條件就會噴錯:
Table::where("CREATE_DATE", $this->date)
->orWhere("MODI_DATE", $this->date)
->get();
SQLSTATE[42000]: Syntax error or access violation: 306 [FreeTDS][SQL Server]The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator. (SQLExecute[306] at /builddir/build/BUILD/php-7.4.26/ext/pdo_odbc/odbc_stmt.c:259) (SQL: select * from "{TABLE}" where "{TABLE}"."CREATE_DATE" = 20060419 or "{TABLE}"."MODIFY_DATE" = 20060419)
這感覺不是 Laravel 套件問題,但這個 driver 我用 PDO 直接下 sql 是可以正常運行的,不知道問題出在哪。
https://laracasts.com/discuss/channels/eloquent/cant-use-wherein-to-query-a-sql-server-2000-using-freetds-driver
3年前也有人跟你一樣
個人猜測是 ORM 再組合的時候 使用到 PDO Prepared Statements (可能MSSQL 版本不相容或是不支援)
PDO 送到 pdo_odbc 這裏就吃到錯誤的語句
https://github.com/php/php-src/blob/PHP-7.4.26/ext/pdo_odbc/odbc_stmt.c
雖然噴錯上的Query語句 你試過沒問題
但是 where 那段可是有做 Prepared Statements 爲了防止 SQL injection
解法就是不要用 where 全部都 RAW Query
看起來應該是 ORM 端出問題沒錯 QQ
https://learnku.com/articles/17367
後來照這篇做 ORM 可以動了
http://chan15.blogspot.com/2021/12/laravel-connet-to-mssql-server-on-centos.html
把測試的過程寫下來了,希望可以幫助到需要的人