PHP to PostgreSQL将unnested数组插入多行

时间:2013-01-25 19:08:25

标签: php arrays postgresql insert

我在PHP数组/变量中有一些数据可以通过INSERT语句插入到PostgreSQL表中。

举一个简单的例子说我有以下信息:

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

(在我的实际应用中,这些是双精度,可能超过1,000个值)

我的postgresql表格中包含“name”,“time”,“elevation”

我想在单个INSERT语句中插入这些内容,并且已经有多种不同的方法来执行此操作。

  1. 一次循环并插入一个数据点(行)。
  2. 在数组上使用unnest()并执行单个插入(最快)
  3. 我的问题是我可以传递单个变量名称,并且非嵌套数组并且每行重复一次名称(数组元素),或者我是否需要为名称构造重复数组,等效count()为其他数组?

    示例声明:

    * cr_query是我们使用的自定义PHP pg_query包装器

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

    这会插入某些表格:

    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中,使用klin下面的方法在一个不需要的语句中用于表面的数组将成为不必要的(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:

    现在所有的“编码”工作都出现了一个新的问题。假设上面的示例列“surface”是double precision类型。

    假设我正在插入一个数组,但是对于这个集合,所有数据都是空的。

    必不可少的是:

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

    但是,此数组的类型为string。为它添加一个值,它就成为该数值的类型,但我需要能够处理它。

    我的问题是:如何将所有空值的unnested数组插入双精度列? (我试图施放:: double precision),但这是不可能的。

1 个答案:

答案 0 :(得分:2)

假设你的cr_query()函数没有做任何神奇的事情,你的代码将会引发postgres语法错误。您可以使用unexst,但必须准备正确的查询文本。 试试你的代码:

$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”以进行查询。 可能最简单的方法是使用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));";