0

テーブルから次のSQLステートメントを取得し、バインド変数を使用して値を置き換えています。ステートメントを実行すると、構文エラーが発生します。lower()関数の結果として発生しているようですが、これを正しく使用していると思います。psqlを使用してステートメントを手動で実行しようとしましたが、指定した値で正常に機能します。誰かがこれについて何かアイデアを持っていますか?$$の'を切り替えてみましたが、効果がありませんでした。

声明

SELECT column_name 
FROM information_schema.columns 
WHERE table_name=lower(':1') 
  and column_name=lower(':2')

置換された値を持つ期待される基本的なステートメント

SELECT column_name 
FROM information_schema.columns 
WHERE table_name=lower('MyTableName') 
  and column_name=lower('MyColumnName')

postgresqlによって実行されるステートメント

SELECT column_name 
FROM information_schema.columns 
WHERE table_name=lower('((E'RWOL_TMA_ROADWORKS'))') 
and column_name=lower('((E'TPHS_CWAY_RESTRICT_TYPE'))')

C#のエラー

ERROR: 42601: syntax error at or near \"MyTableName\"

PostgreSQLログファイルのエラー

2012-04-16 11:36:15 BST ERROR:  syntax error at or near "RWOL_TMA_ROADWORKS" at character 80
2012-04-16 11:36:15 BST STATEMENT:  SELECT column_name FROM information_schema.columns WHERE table_name=lower('((E'RWOL_TMA_ROADWORKS'))') and column_name=lower('((E'TPHS_CWAY_RESTRICT_TYPE'))')

編集:取得および実装コードはC#で記述されています。私は、データベース接続の基本クラスとnpgsqlプロバイダーファクトリを使用して、接続を確立し、クエリを実行し、データを取得します。このメソッドは、lower()関数を使用しようとするこのメソッドを除いて、変数などをバインドするこのメソッドを使用する他のすべてのクエリで機能します。

編集:バインディングエージェントが値の引用を処理できるように引用符を完全に削除しようとしましたが、これにより同じ構文エラーが発生しました。

編集:ロギングを有効にし、postgresqlが実行されているという実際のステートメントを追加しました。

4

3 に答える 3

1

との周り:1に引用符を使用するべきではないかもしれません:2。バインド変数をサポートするほとんどのAPIは、値を正しく引用します。

于 2012-04-16T09:57:27.020 に答える
1

lower()関数の問題ではなく、バインド変数の処理の問題だと思います。

@Adrianが示唆しているように、バインド変数を引用符で囲まないようにしてください。また、データベースのログも参照する必要があります。そこで何が起こっているかについての詳細が表示されます。

編集:使用:

SHOW data_directory;
SHOW log_directory;

SQLDATAディレクトリの場所とログの場所を検索するステートメント。ログパスが相対パスの場合は、DATAディレクトリからの相対パスになります。

そこに行き、最近変更されたファイルを見つけて、内容を確認します。デフォルトのPostgreSQL構成でエラーメッセージが表示されるはずです。

また、ミドルウェア/ファクトリレベルでもデバッグを有効にするとよいでしょう。

于 2012-04-16T09:58:44.853 に答える
1

vyegorovは正しい方向に進んでいると思います。プレースホルダーには、何か面白いことがあります。

エラーが含まれていないため、2番目の例は置換後の実際のクエリではないと思います。それはどこから来たのですか、そしてなぜ実際のクエリを提供しないのですか?PostgreSQLでステートメントロギングをオンにしていますか?

また、構文エラーが疑われます。エスケープされた二重引用符はどうなっているのでしょうか。それらは実際には二重引用符であり、二重引用符ではありませんか?

  1. プレースホルダーを一重引用符で囲む必要がありますか?通常、ドライバーがそれを管理します。

  2. どこかで値を二重引用符で囲んでいないのですか?

実際のSQLを取得し、引用符を見てください。問題は明らかだと思います。

更新:SQLが追加されました

投稿されたステートメントのエラーは次のとおりです。

lower('((E'RWOL_TMA_ROADWORKS'))')

ここには2つのレベルの引用があります。追加したものを削除すると、次のようになります。

lower((E'RWOL_TMA_ROADWORKS'))

有効な繰り返し括弧を無視します(E'...'は、cスタイルのエスケープされた文字列の構文です-google around standard_conforming_strings)。

于 2012-04-16T09:59:40.797 に答える