5

アプリを mssql 関数から PDO に移動することになっています。回避策がないように見える素敵な小さなバグを見つけるまで、すべてがスムーズに実行されていました。

これが私の準備されたリクエストです:

$req_action="INSERT INTO [".DB_SCHEMA."].[dbo].[".ACTION_TABLE."] 
([ID_CONTACT]
,[ID_ADN]
,[TYPE_ACTION]
,[MOTIF_ENTRANT]
,[COMMENTAIRES_APPEL]
,[CODE_CAMPAGNE]
,[EMAIL]
,[SUJET]
,[STATUT_EMAILING]
,[DATE_ENVOI]
,[DELAI_OUVERTURE]
,[MAIL_CLIENT]
,[DATE_OUVERTURE]
,[LIEN_CLIQUE]
,[DELAI_CLIC]
,[DATE_CLIC]
,[DATE_ACTION]
,[USER_ID]
,[LOGIN]
,[DATE_CHARGEMENT]
)
VALUES
(''
,''
,'e-mailing'
,''
,''
,''
,:email
,:sujet
,:statut
,convert(datetime,:date_envoi,103)
,:delai
,:mail
,convert(datetime,:date_ouverture,103)
,:lien_clic
,:delai_clic
,convert(datetime,:date_clic,103)
,convert(datetime,:date_action,103)
,'1'
,'AUTO'
,getdate()
)";

と私のバインディング:

$prep_req_action->bindValue(":email",$email,PDO::PARAM_STR);
$prep_req_action->bindValue(":sujet",$sujet,PDO::PARAM_STR);
$prep_req_action->bindValue(":statut",$statut_emailing,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_envoi",$sql_date_envoi,PDO::PARAM_STR);
$prep_req_action->bindValue(":delai",$delai_ouverture,PDO::PARAM_STR);
$prep_req_action->bindValue(":mail",$mail_client,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_ouverture",$sql_date_ouverture,PDO::PARAM_STR);
$prep_req_action->bindValue(":lien_clic",$lien_clique,PDO::PARAM_STR);
$prep_req_action->bindValue(":delai_clic",$delai_clic,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_clic",$sql_date_clic,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_action",$sql_date_action,PDO::PARAM_STR);

問題は、PHP 変数の 1 つがたまたま空の文字列である場合です (自動化された csv ファイルからのもので、実際には頻繁に発生します)。SQL サーバーはエラー HY104 (無効な精度) を返します。

すべてのフィールドが NULL 許可されているため、PDO::ATTR_ORACLE_NULLS属性を切り替えてPDO::NULL_EMPTY_STRING空の文字列を NULL に変換しましたが、動作はまったく同じです。

私が見つけた唯一の回避策は、変数が空であるかどうかをテストして、バインドする前に php null に設定することです。

$lien_clique = (empty($lien_clique)) ? null : $lien_clique;

これは実際には機能しますが、NULL_EMPTY_STRING への PDO 属性がそれを行う必要があるように感じます。更新するクエリが大量にあり、この tweek ですべてを保護したくありません。

問題の理由と解決方法について何か考えがある人はいますか?

参考までに: Linux 上の PHP 5.3.1、pdo_sqlsrv 3.0、および SQL Server 2000。

4

1 に答える 1

0

文字列列にサイズが設定されているように聞こえますが、データベースではおそらく挿入時にサイズを指定する必要があります。

使ってみて...

$stmt->bindValue(":field",$value,PDO::PARAM_STR,$length);

エラーが発生したフィールドで、$length はデータベースで指定されているフィールドのサイズです。これを行うのは面倒ですが、しばらく前に ODBC ドライバーでこの問題に遭遇したことを覚えています。

于 2012-12-11T04:36:03.350 に答える