1

このコードはexecuteQueries.ecファイルにあります

sprintf(sqlQuery,
"select distinct e.emp_id, e.join_date \
from employees e
where e.emp_id in (?) and e.dob <= '%s')");

$prepare empDataStmt from $sqlQuery;
if (sqlca.sqlcode)
{
    fprintf(stderr, "Error %d in prepare empDataStmt%s\n",
    sqlca.sqlcode, sqlQuery);
    return 0;
}
$declare empDataCursor cursor for incptDatesStmt;

if (pcs_sql_check("Error in declaring empDataCursor Stmt"))
{
    return 1;
}

$open empDataCursor using $empIds_,dob_ ;

コードをdbxして印刷するとempIds_、コンソールに次のように表示されます。

""04-Emp1","W2-Emp2""

これは、empIds_の内容が"04-Emp1","W2-Emp2" (引用符を含む)であることを意味します。問題は、その数がempIds1から100または500までの範囲である可能性があるということです。たとえば、次のようにすることもできます。

"04-Emp1","W2-Emp2","04-Emp4","W2-Emp3","0A-Emp1","E2-Emp7"

このため、コードを機能させることができません。誰かが「?」を使用してこのコードを書くのを手伝ってもらえますか?任意の数を処理できるパラメーター化されたクエリの場合empIds。empIds_のコンテンツには、常に二重引用符が埋め込まれていることに注意してください。これが良いことなのか悪いことなのかはわかりませんが、それを防ぐために何もできません。

4

1 に答える 1

0

マイナーな転換

あなたは私たちに見せるものにいくつかの構文上の問題があります:

sprintf(sqlQuery,
"select distinct e.emp_id, e.join_date \
from employees e
where e.emp_id in (?) and e.dob <= '%s')");

それはコンパイルされません。の後に2番目の円記号が必要ですemployees e。文字列のバックスラッシュ改行は避けることを強くお勧めします。代わりに文字列連結を使用してください。

sprintf(sqlQuery, "select distinct e.emp_id, e.join_date from employees e "
                  "where e.emp_id in (?) and e.dob <= '%s')");

文字列の2つの部分の間に空白があることに注意してください(コメントも空白としてカウントされます)。Cコンパイラは、このような文字列を1つの文字列に連結します。

これで、sprintf()呼び出しはCソースレベルで構文的に正しくなります。が含まれていて、コピーする文字列が指定されていないため、意味的に正しく%sありません。おそらく?、日付のプレースホルダーを2番目のパラメーターとしてステートメントに渡すために使用する必要$openがあります(ただし、実際にはそのプレースホルダーはありません)。

次に、次のように記述して、明示的な準備操作を回避できます。

$ DECLARE empDataCursor FOR
    SELECT DISTINCT e.emp_id, e.join_date
      FROM employees e 
     WHERE e.emp_id IN ($empIds_) AND e.dob <= $dob_;

核心

ただし、残念ながら、これはうまくいきません。問題の核心は、IN句の値のリストとして文字列を渡そうとしていることです。それは単にそのようには機能しません。値が1つある場合は、プレースホルダー(?)が1つ必要です。2つの値がある場合は、2つのプレースホルダーなどが必要です。

したがって、最終的には完全に準備されたステートメントに戻り、empIdsを文字列に置き換えます。

 int reqlen;

 reqlen = snprintf(sqlQuery, sizeof(sqlQuery), "SELECT DISTINCT e.emp_id, e.join_date"
                       " FROM employees e WHERE  e.emp_id IN (%s) AND e.dob <= '%s'",
                       empIds_, dob_);

 if (reqlen >= sizeof(sqlQuery))
     ...truncated SQL...larger sqlQuery needed...

 $ PREPARE empDataStmt FROM $sqlQuery;
 ...SQL error check...
 $ DECLARE empDataCursor FOR empDataStmt;
 ...SQL error check...

 $ OPEN empDataCursor;   /* No USING clause! */
 ...SQL error check...

 ...code as before...
于 2012-05-04T19:49:43.553 に答える