1

INSERT ステートメントを介して PostgreSQL テーブルに挿入する準備ができている PHP 配列/変数にいくつかのデータがあります。

簡単な例として、次の情報があるとします。

$name= 'someName';
$time = array(1,2,3);
$elevation = array(100,200,300);

(私の実際のアプリケーションでは、これらは倍精度で、1,000 以上の値になる可能性があります)

また、列「name」、「time」、「elevation」を持つpostgresqlテーブルもあります

これらを単一の INSERT ステートメントに挿入したいのですが、これを行うには複数の異なる方法が与えられています。

  1. 一度に 1 つのデータ ポイント (行) をループして挿入します。
  2. 配列で unnest() を使用し、単一の挿入を行います (最速)

私の質問は、単一の変数名とネストされていない配列を渡して、行ごとに (配列要素ごとに) 名前を繰り返すことができるか、または他の配列と同等の count() という名前の繰り返し配列を作成する必要があるかということです。

ステートメントの例:

*cr_query は、私たちが使用するカスタム PHP pg_query ラッパーです

cr_query($conn,"INSERT INTO sometable (name,time,elevation) VALUES ({$name},{unnest($time)},{unnest($elevation)}););

これはsometableに挿入されます:

ID     name      time    elevation
1     someName     1        100
2     someName     2        200
3     someName     3        300

私はここで正しいですか、それとも何か他のことをする必要がありますか?

編集:

別の変数「表面」もあるとしましょう。Surface は double 値または NULL にすることができます。したがって、次のようにテーブルに挿入したいと思います。

ID     name      time    elevation    surface
1     someName     1        100          50
2     someName     2        200         NULL
3     someName     3        300          100

PHP では、unnest ステートメントの surface の配列の下で klin によって指定されたメソッドを使用すると unnest(array[50,,100]); になります。これにより、次のようなエラーがスローされます。

(私の実際のデータからのエラー)

ERROR: syntax error at or near "," LINE 3: ...-6,5.75E-6,5.75E-6,5.75E-6,5.75E-6]),unnest(array[,,,,,,,,,]... ^

編集2:

すべての「エンコーディング」が機能するようになったので、新しい問題が発生しました。上記の例の列「表面」が倍精度型であるとします。

配列を挿入するとしますが、このセットではすべてのデータが null です。

重要な部分は次のとおりです。

unnest(array[null,null,null,null,null,null,null,null,null,null])

ただし、この配列は文字列型です。それに単一の値を追加すると、その数値の型になりますが、これを処理できる必要があります。

私の質問は次のとおりです。すべての null 値のネストされていない配列を倍精度列に挿入するにはどうすればよいですか? (私は ::double precision をキャストしようとしました) しかし、それは不可能です。

4

1 に答える 1

2

cr_query() 関数が魔法のようなことをしていないと仮定すると、コードは postgres 構文エラーを発生させます。unnest を使用できますが、適切なクエリ テキストを準備する必要があります。コードを試してください:

$name= 'someName';
$time = array(1,2,3);
$elevation = array(100,200,300);
echo "INSERT INTO sometable (name,time,elevation) VALUES ".
    "({$name},{unnest($time)},{unnest($elevation)})"

echo: INSERT INTO sometable (name,time,elevation) VALUES (someName,{unnest(Array)},{unnest(Array)})

明らかに、これは postgres に送りたいものではありません。これを修復する方法は?

$name= 'someName';
$time = array(1,2,3);
$elevation = array(100,200,300);
$timestr = 'array['. implode(',', $time). ']';
$elevstr = 'array['. implode(',', $elevation). ']';
echo "INSERT INTO sometable (name,time,elevation) ".
    "VALUES ('$name',unnest($timestr),unnest($elevstr));"

echo: INSERT INTO sometable (name,time,elevation) VALUES ('someName',unnest(array[1,2,3]),unnest(array[100,200,300]));

これは正しいクエリだと思います。テキスト変数 '$name' を一重引用符で囲んでいることに注意してください。


配列に null がある場合は、クエリ用に準備されたテキストですべての空の文字列を「null」に置き換える必要があります。おそらく最も簡単な方法は、str_replace() を使用することです。変換がより複雑になるにつれて、その目的のために関数 ("pgstr()" など) を作成すると便利です。

function pgstr($array) {
    $str = 
        str_replace('[,', '[null,', 
        str_replace(',]', ',null]', 
        'array['. implode(',', $array). ']'));
    while (strpos($str, ',,') > 0) $str = str_replace(',,', ',null,', $str);
    return $str;
    }

$name= 'someName';
$time = array(1,2,3,4);
$elevation = array(100,null,300,null);
$surface = array(null,null,3.24,null);
$timestr = pgstr($time);
$elevstr = pgstr($elevation);
$surfstr = pgstr($surface);
echo 
    "INSERT INTO sometable (name,time,elevation,surface) ".
    "VALUES ('$name',unnest($timestr),unnest($elevstr),unnest($surfstr));";
于 2013-01-25T22:46:08.650 に答える