php - Can't select a column name containing accent
one text
Problem
I'm actually on a new website project with Symfony 5. As I have to access an historical database where all of our products details are stored, I have to use AdoDb so I can use odbc driver (As doctrine doesn't allow to use it).
When I try selecting a field with accent, the query failed and throw a S0022 error code.
Full error message is :
"[Simba][SQLEngine] (31750) Column not found: ar1_h?�ndlerpreis"
See that ar1_h?�ndlerpreis
contain a "?�" character which seems to be the problem.
What I have already tried
Here is my code for the query.
Look at the ar1_h?�ndlerpreis
which is present into the "Prepare" function first parameter.
$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);
I have try to edit the field ar1_h?�ndlerpreis in my query string as :
- ar1_h[?�]ndlerpreis (As told here)
- `ar1_h?�ndlerpreis` (Surrounding with backstick ... Since I know that some fields need to be escaped)
- ar1_h?�ndlerpreis || '' (As explain here it may have convert the column name to an expression an should not generate error)
- ar1_h?�ndlerpreis + 0 (Same as previous one, it may have been converted to an expression)
I have also tried to change encoding character for accessing database :
$this->_db->setConnectionParameter('CharacterSet','UTF-8');
(As explain here)
But nothing do...
Some code
I provide you more code to see if i did something wrong.
This is my ADOdbConnection Service which i use when i need to connect to the historical database. Most of the time, i use Doctrine for the website specific database.
<?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;
}
}
It work as it should, doing a connection to the database.
Then, this is my DAL for the product (Article) table :
<?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;
}
}
This code display the following result :
ArticleDal.php on line 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 on line 39: "S0022"
ArticleDal.php on line 40: "[Simba][SQLEngine] (31750) Column not found: ar1_h?�ndlerpreis"
ArticleDal.php on line 41: false
And there is an example of what return a SELECT *
(I truncate it because it have 360 columns...) :
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"
...
It's weird those little 'b' in front of field with accent (For ar1_h?�ndlerpreis and ar1_preislisten?�nder). dump() is the debug function from Symfony framework.
If i use var_dump instead of dump, i got this result :
["ar1_h???ndlerpreis"]=> string(4) "3.77"
Thank you.
Source