2012-03-03 11 views
0

Cでデータが混在した挿入文字列を作成したため、行を挿入できません。
私のロケールでは小数点区切り記号としてコンマを使用する浮動小数点で問題が発生することがあります。挿入するためのPostgreSQL、libpqで浮動小数点を挿入する

ERROR: INSERT has more expressions than target columns
LINE 1: ...0:11:37.097203 +0100', 'Book about solving issues', '', 'PCS', 0,000000)

コード:挿入時にそう

、私はエラーメッセージが表示されます

snprintf(sqlInsert, sizeof(sqlInsert), "INSERT INTO mytable (dtbl_id, kni, dtmp, iname, tagname, mea, klc) VALUES 
(%d, '%s', '%s', '%s', '%s', '%s', %f)", o, k, dt, es, tagname, meas)), IL.klc); 

どのように適切に倍精度数を挿入するには、このような状況を解決するために?

答えて

1
rc = snprintf(sqlInsert, sizeof sqlInsert 
, "INSERT INTO mytable (dtbl_id, kni, dtmp, iname, tagname, mea, klc)" 
" VALUES    (%d,  '%s', '%s', '%s', '%s', '%s', %f);" 
         , o,  k, dt, es, tagname, meas, IL.klc); 

UPDATE:ロケールに問題がある場合、setlocale()はプログラム内でローカルに設定するのに役立ちます。 LC_ALL = POSIX(またはC)は常に存在する必要があります。 (これがうまく{%E%F%G}のいずれかの形式は、ロケール設定に影響されないことがあり得る)

次のプログラムは、(はsetlocaleの使用を示す):

#include <stdio.h> 
#include <locale.h> 

#pragma DONT define DEFAULT_LOCALE "POSIX" 
#define DEFAULT_LOCALE "nl_NL.utf8" 
/* LC_NUMERIC LC_ALL */ 

int main(int argc, char **argv) 
{ 
    double val; 
    char *old, *new; 

    val = 1024 * 1024; 
    val /= 10; 

    printf ("Original: Val=%f\n", val); 
    new = argv[1] ? argv[1] : DEFAULT_LOCALE ; 

    old = setlocale (LC_ALL, new); 

    printf("Old=%s, New=%s\n", old, new); 
    printf ("After change: Val=%f\n", val); 

    new = setlocale (LC_ALL, old); 

    printf("Old=%s, New=%s\n", new, old); 
    printf ("After restore: Val=%f\n", val); 
return 0; 
} 

出力:

[email protected]:./a.out 
Original: Val=104857.600000 
Old=nl_NL.utf8, New=nl_NL.utf8 
After change: Val=104857,600000 
Old=nl_NL.utf8, New=nl_NL.utf8 
After restore: Val=104857,600000 
[email protected]: 

は、マニュアルを読んだ後、私は古い設定を戻すためにsetlocale()を予想、それはケースではないようです。たぶん私は意図せずにいくつかのグローバル設定を変更しました: - [

UPDATE:明示的に引数を* printf()関数にキャストするのは良いことです。

#include <locale.h> 
(void) setlocale (LC_NUMERIC, "POSIX"); 

rc = snprintf(sqlInsert, sizeof sqlInsert 
, "INSERT INTO mytable (dtbl_id, kni, dtmp, iname, tagname, mea, klc)" 
" VALUES    (%d, '%s', '%s', '%s', '%s', '%s', %f);" 
        , (int) o,  k, dt, es, tagname, meas, (double) IL.klc); 
+0

これはまだ動作しません。とにかく数字を話すときは、ロケールについて話すのは奇妙です。ほとんどのヨーロッパでは小数点区切り記号としてカンマが使用されています。そうですね、私はダブルスを文字列に変換して文字列のように格納できますが、データベースに文字列がありません。ほとんどの場合は完全に受け入れられません。 –

+2

'))も修正しましたか? snprintf()の後にバッファには何が入っていますか?ところで、私の場合、ロケールはlibc-stuffには適用されていないようです。マニュアルページは、古いバージョンでは標準動作が異なることを示しています。 – wildplasser

+0

はい、修正します。 IL.klcはファイルから読み込まれる8ビットの数値です。 printf( "%f \ n"、IL.klc)を実行すると、私は0,000000を得る。バッファにも同じです。また、数字でうまく動作するMySqlと同じです。数字をファイルに書き込むと、小数点記号に関係なく8ビットにパックされます。だから私はPQがバイナリ形式で私の番号を保存すると思った。私はまだ何かが間違っていると思います。なぜなら、番号を記憶することは、PQのような巨大なシステムのための基本的な操作であり、ロケールに接続してはならないからです。 –

関連する問題