コンテンツにスキップ

Named Bind Parameter

Named Bind Parameterは、SQLの値の位置に:name形式の名前を指定し、実行時に値をバインドする機能です。 繰り返すパラメーターの意味を名前で表せるため、SQLとアプリケーションコードの対応関係を明確に保てます。

SELECT ID, NAME
FROM SENSOR_DATA
WHERE ID = :id;

名前の構文

名前付きマーカーは次の形式を使用します。

:[A-Za-z_$][A-Za-z0-9_$]*
区分
有効な名前:id, :sensor_id, :value2, :_from_time, :select
無効な名前:1id, :, ::id

複数のSDKで同じSQLを共有する場合は、[A-Za-z][A-Za-z0-9_]*形式の名前を推奨します。

パラメーター名は大文字と小文字を区別します。:VALUE:value:VaLuEは異なる名前です。 .NETのMachParameterCollectionは、既存プロバイダーとの互換性のため、大文字と小文字を区別せず名前を検索します。

使用できる位置

名前付きマーカーは、値や式を指定する位置で使用します。

SELECT ID, NAME, VALUE
FROM SENSOR_DATA
WHERE CREATED_AT >= :from_time
  AND CREATED_AT < :to_time
  AND VALUE >= :minimum_value
ORDER BY CREATED_AT
LIMIT :row_count OFFSET :start_row;

次のような識別子やSQL構造は、パラメーターに置き換えられません。

SELECT * FROM :table_name;               -- 使用不可
SELECT :column_name FROM SENSOR_DATA;     -- 列識別子の置き換えではない
SELECT * FROM SENSOR_DATA ORDER BY ID :direction; -- 使用不可

動的な識別子が必要なら、アプリケーションで許可リストを検査してからSQLを構成します。

文字列とSQLコメント内のコロンは、パラメーターとして認識されません。

SELECT ':not_a_parameter'
FROM SENSOR_DATA
WHERE ID = :id /* :ignored */;

パラメーターの出現順序

パラメーター数は一意な名前の数ではなく、SQL内の出現回数で数えます。 次のSQLにはtargetが2回現れるため、パラメーターは2つです。

SELECT ID, NAME
FROM SENSOR_DATA
WHERE ID = :target
   OR PARENT_ID = :target;
  • SQLNumParams()2を返します。
  • 位置指定APIは、1番目と2番目の位置を個別にバインドします。
  • 名前指定APIは、1つのtarget値を同名の両方の位置に適用します。
  • パラメーターメタデータには、各位置が別の項目として現れます。

1つのSQL文で使用できるパラメーターの出現回数は、最大256です。

位置指定マーカーとの関係

低レベルの位置指定APIは、?:nameをSQLの出現順にバインドできます。 名前・オブジェクト・マッピングによるAPIは、匿名マーカー?と名前付きマーカーを併用するとエラーを返します。 1つのSQL文では1種類のマーカーを使用してください。

方式SQLマーカーバインド
位置指定?SQL出現順の1始まりの位置番号
名前付きSQLと位置指定API:nameSQL出現順の1始まりの位置番号
名前指定API:nameパラメーター名

DMLでの使用例

Named Bind Parameterは、既存のプリペアドステートメントと同じ型規則を使用します。

INSERT INTO SENSOR_DATA
    (ID, PARENT_ID, NAME, VALUE, CREATED_AT)
VALUES
    (:id, :parent_id, :name, :value, :created_at);

Named Bind Parameterは、テーブルごとのDMLポリシーやEdition制約を変更しません。 サポートされるDMLと条件は、DML構文および サポート範囲と制約を参照してください。

Standard EditionとCluster Editionは、同じ:name構文と位置番号規則を使用します。 実行可能なSQLとテーブルタイプは、各Editionの既存のサポート範囲に従います。

TAGデータUPDATEでの使用

Machbase 8.7.0から、Standard EditionのTAGデータUPDATEでは、WHERE句のNAMEとBASETIME条件値に名前付きマーカーを使用できます。

UPDATE sensor_tag
   SET value = :value,
       status = :status,
       note = :note
 WHERE name = :name
   AND time = :time;

同じプリペアドステートメントの再実行時に、SET、NAME、TIMEの値を新しくバインドできます。 一致する行がなければ、影響行数0で成功します。 バインドの使用にかかわらずタグ選択条件とBASETIME条件は両方必要で、SET対象列の制約も変わりません。

サポートされる条件形式とパラメーターメタデータは、 TAGデータUPDATEを参照してください。

CTEでの使用

Standard Editionでは、CTE本文とメインのSELECTでNamed Bind Parameterを使用できます。

WITH FILTERED AS (
    SELECT ID, NAME, VALUE
    FROM SENSOR_DATA
    WHERE ID > :minimum_id
      AND NAME = :label
)
SELECT ID, NAME, VALUE
FROM FILTERED
WHERE ID = :target_id
ORDER BY ID;

上のSQLのパラメーターの位置番号は、minimum_idlabeltarget_idの順です。 CTEのサポート範囲とStandard Edition制約は、WITH / CTE構文を参照してください。

NULLとデータ型

NULLは、各SDKの標準のNULL値またはインジケーターで渡します。

SDKNULL値
Machbase SQLCLIインジケーターのSQL_NULL_DATA
ODBCインジケーターのSQL_NULL_DATA
JDBCnull
Node.js/TypeScriptnull
PythonNone
.NETDBNull.Value

column = :valueにNULLをバインドしても、column IS NULLと同じ条件にはなりません。 NULLを検索するには、SQLのNULL比較規則に従ってIS NULLを使用します。

INTEGERVARCHARDOUBLEDECIMALNUMERICDATETIMEなど、既存のプリペアドステートメントのデータ型を使用できます。 DECIMALNUMERICの精度を保持するには、SDKのdecimal型または文字列表現を使用してください。

SDK別のバインド方法

SDKまたはツール名前による使用方法
Machbase SQLCLISQLBindParameterByName(), SQLBindParameterByNameW()
ODBC:nameのSQLをSQLBindParameter()の位置番号でバインド
JDBCMachPreparedStatement.setObject(String name, Object value)
Node.js/TypeScript配列は位置指定、オブジェクトは名前指定入力
Python DB-APImappingを渡す。2.4のprepared cursorは、呼び出し間で:name%(name)sを再使用
.NETMachCommand.Parameters.AddWithValue(":name", value)
Go nativeapi.Named("name", value)
Go database/sqlsql.Named("name", value)
machsqlSQLは:name、値は$1$2の順で指定

詳細なAPIとエラー処理は、開発ツール連携machsqlコマンド・オプションリファレンスを参照してください。

互換性とエラー

Machbase 8.7.0の名前指定SDK APIには、この機能に対応するクライアントとサーバーの両方が必要です。 旧バージョンと併用する必要がある場合は、?と位置指定APIを使用してください。

状況代表的なエラー
必要な名前がないmissing parameter
SQLにない名前を渡すunknownまたはextra parameter
名前指定と位置指定を混在sequenceまたはmixed error
値の型がSQL型と合わないtypeまたはconversion error
名前指定APIを旧サーバーに使用unsupported

本番コードでは、エラー文字列よりSQLSTATE、エラーコード、例外型を優先して確認してください。 バージョンの組み合わせごとの動作とSDK別のエラーコードは、 クライアント・サーバープロトコル互換性を参照してください。

最終更新日