問題
私は実際に Symfony 5 を使用した新しい Web サイト プロジェクトに参加しています。すべての製品の詳細が保存されている履歴データベースにアクセスする必要があるため、odbc ドライバーを使用できるように AdoDb を使用する必要があります (教義では使用が許可されていないため)。それ)。
アクセントのあるフィールドを選択しようとすると、クエリが失敗し、S0022エラー コードがスローされます。完全なエラー メッセージは次のとおりです。
"[Simba][SQLEngine] (31750) Column not found: ar1_händlerpreis"
ar1_händlerpreis
問題と思われる「ä」文字が含まれていることを確認してください。
私がすでに試したこと
これがクエリのコードです。ar1_händlerpreis
「Prepare」関数の最初のパラメーターに存在する を見てください。
$strIn = "";// Adodb odbc doesn't support IN(?) with an array parameter (string are quoted automatically)
foreach ($array_article_number as $number) {
$strIn .= "?,";
}
$strIn = substr($strIn, 0, -1); // Last one doesn't need ',' characters as it's the last one.
$query = $this->_db->Prepare("SELECT ar1_artikelnummer, ar2_mwststeuerschl, ar1_bestand, ar1_klassifizierung, ar1_bezeichnung3, ar1_apothekenpreis, ar1_händlerpreis AS apreis FROM artikeldaten WHERE ar1_artikelnummer IN(" . $strIn . ")");
$datas = $this->_db->Execute($query, $array_article_number);
クエリ文字列のフィールド ar1_händlerpreis を次のように編集しようとしました。
- ar1_h[ä]ndlerpreis (ここで述べたように)
- `ar1_händlerpreis` (バックスティックで囲む ... 一部のフィールドをエスケープする必要があることがわかっているため)
- || ar1_handlerpreis || '' (ここで説明しているように、列名を式に変換している可能性がありますが、エラーは発生しません)
- ar1_händlerpreis + 0 (前のものと同じ、式に変換されている可能性があります)
また、データベースにアクセスするためのエンコーディング文字を変更しようとしました:
$this->_db->setConnectionParameter('CharacterSet','UTF-8');
(ここで説明するように)
しかし、何もしません...
いくつかのコード
私が何か間違ったことをしたかどうかを確認するためのコードをさらに提供します。
これは、履歴データベースに接続する必要があるときに使用する ADOdbConnection サービスです。ほとんどの場合、私は Web サイト固有のデータベースに Doctrine を使用しています。
<?php
namespace App\Services;
use ADOConnection;
class ADOdbConnection
{
private ADOConnection $_db;
/**
* AdodbConnection constructor.
* @param $host
* @param $user
* @param $pwd
* @param $db_name
*/
public function __construct($host, $user, $pwd, $db_name)
{
$this->_db = ADONewConnection('odbc');
$this->_db->setConnectionParameter('CharacterSet','UTF-8');
$this->_db->connect('DRIVER={CONZEPT 16 ODBC-Treiber (64 bit)};SERVER='.$host.';DB='.$db_name.';', $user, $pwd, $db_name);
}
public function getDb() : ADOConnection{
return $this->_db;
}
}
データベースへの接続を行い、正常に機能します。
次に、これは製品 (記事) テーブルの DAL です。
<?php
namespace App\Services\DAL_w2;
use ADOConnection;
use App\Services\ADOdbConnection;
class ArticleDal
{
private ADOConnection $_db;
public function __construct(ADOdbConnection $ADOdbConnection)
{
$this->_db = $ADOdbConnection->getDb();
$this->_db->setCharset('UTF-8');
$this->_db->SetFetchMode(ADODB_FETCH_ASSOC);
}
/**
* Join w2 database for every article number given
* @param array $array_article_number An array of article number.
* @return array|null An array of article from w2 article's table or null
*/
public function getDataForListArticleFromArticleNumber(array $array_article_number): ?array
{
$res = null;
if (count($array_article_number)) {
$strIn = "";// Adodb doesn't support IN(?) with an array parameter (string are quoted automatically)
foreach ($array_article_number as $number) {
$strIn .= "?,";
}
$strIn = substr($strIn, 0, -1); // Last one doesn't need ',' characters as it's the last one.
$query = $this->_db->Prepare("SELECT ar1_artikelnummer, ar2_mwststeuerschl, ar1_bestand, ar1_klassifizierung, ar1_bezeichnung3, ar1_apothekenpreis, ar1_händlerpreis + 0 AS apreis FROM artikeldaten WHERE ar1_artikelnummer IN(" . $strIn . ")");
dump($query);
$datas = $this->_db->Execute($query, $array_article_number);
dump($this->_db->_errorCode);
dump($this->_db->_errorMsg);
dump($datas);
die();
// Assign article number as array key
$res = array();
foreach ($datas as $article_data) {
$res[$article_data['ar1_artikelnummer']] = $article_data;
}
}
$res = $res ?: null; // If we don't have any data
return $res;
}
}
このコードは次の結果を表示します。
ArticleDal.php の 37 行目: "SELECT ar1_artikelnummer, ar2_mwststeuerschl, ar1_bestand, ar1_klassifizierung, ar1_bezeichnung3, ar1_apothekenpreis, ar1_händlerpreis + 0 AS apreis FROM artikeldaten WHERE ar1_artikelnummer IN(?,?,?,?,?,?,? ?,?,?,?,?,?,?,?,?,?,?)」
ArticleDal.php の 39 行目: "S0022"
ArticleDal.php の 40 行目: "[Simba][SQLEngine] (31750) 列が見つかりません: ar1_händlerpreis"
41 行目の ArticleDal.php: false
そして、何を返すかの例がありますSELECT *
(360列あるため、切り捨てます...):
0 => array:360 [▼
"ar1_artikelnummer" => "0002446"
...
"ar1_preislistenartik" => "0"
"ar1_preislistenpreis" => "0"
b"ar1_preislistenänder" => null
"ar1_preislistenprneu" => "0"
"ar1_preislistenneuab" => null
"ar1_collianz" => "1"
"ar1_tiefstpreis_brut" => "0"
"ar1_ean_nummer" => ""
"ar1_faxpreislistenar" => "0"
"ar1_inetrnetartikel" => "0"
"ar1_unterwarengruppe" => "1"
"ar1_verbot_in_stl" => "1"
"ar1_apothekenpreis" => "5.82"
b"ar1_händlerpreis" => "3.77"
...
フィールドの前にあるアクセント付きの小さな「b」は奇妙です (ar1_händlerpreis と ar1_preislistenänder の場合)。dump()は Symfony フレームワークのデバッグ関数です。
ダンプの代わりに var_dump を使用すると、次の結果が得られました。
["ar1_h�ndlerpreis"]=> string(4) "3.77"
ありがとうございました。