ODBCで準備およびバインドされた次のステートメントを使用します。
SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
AL32UTF8文字セットのOracle10gデータベースへのODBC3.0接続で実行すると、を使用してwchar_t文字列にバインドした後でもSQLBindParameter(SQL_C_WCHAR)
、エラーORA-12704:文字セットの不一致が発生します。
なんで?私はwcharとしてバインドしています。wcharはNCHARと見なされるべきではありませんか?
パラメータを変更してラップするとTO_NCHAR()
、クエリはエラーなしで機能します。ただし、これらのクエリは複数のデータベースバックエンドに使用されるため、OracleテキストバインディングだけにTO_NCHARを追加したくありません。足りないものはありますか?TO_NCHARハンマーなしでこれを解決する別の方法は?
検索やマニュアルで関連するものを見つけることができませんでした。
詳細...
- エラー
SELECT (CASE profile WHEN '_default' THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
- わかった
SELECT (CASE profile WHEN TO_NCHAR('_default') THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
SQL> describe engine_properties; 名前ヌル?タイプ -------------------------------------------------- --------------------------- EID NOT NULL NVARCHAR2(22) LID NOT NULL NUMBER(11) PROFILE NOT NULL NVARCHAR2(32) PKEY NOT NULL NVARCHAR2(50) VALUE NOT NULL NVARCHAR2(64) READONLY NOT NULL NUMBER(5)
TO_NCHARのないこのバージョンは、SQL ServerとPostgreSQL(ODBC経由)およびSQLite(直接)で正常に機能します。ただし、Oracleでは「ORA-12704:文字セットの不一致」が返されます。
SQLPrepare(SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;) = SQL_SUCCESS
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR,
SQL_VARCHAR, 32, 0, "_default", 18, 16) = SQL_SUCCESS
SQLExecute() = SQL_ERROR
SQLGetDiagRec(1) = SQL_SUCCESS
[SQLSTATE: HY000, NATIVE: 12704, MESSAGE: [Oracle][ODBC]
[Ora]ORA-12704: character set mismatch]
SQLGetDiagRec(2) = SQL_NO_DATA
TO_NCHARを使用する場合は問題ありません(ただし、SQL Server、Postgres、SQLiteなどでは機能しません)。
SQLPrepare(SELECT (CASE profile WHEN TO_NCHAR(?) THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;) = SQL_SUCCESS
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR,
SQL_VARCHAR, 32, 0, "_default", 18, 16) = SQL_SUCCESS
SQLExecute() = SQL_SUCCESS
SQLNumResultCols() = SQL_SUCCESS (count = 1)
SQLFetch() = SQL_SUCCESS