# 45.3.内置函数

45.3.1. 从PL/Perl访问数据库

45.3.2. PL/Perl中的实用函数

# 45.3.1.从PL/Perl访问数据库

可以通过以下函数从Perl函数访问数据库本身:

``spi_执行查询(*查询* [, *最大行数*])

spi_执行查询执行SQL命令,并将整个行集作为对哈希引用数组的引用返回。*只有在知道结果集相对较小时,才应使用此命令。*下面是一个查询示例(选择命令),具有可选的最大行数:

$rv = spi_exec_query('SELECT * FROM my_table', 5);

这将从表中返回最多5行我的桌子如果我的桌子他有一个专栏我的专栏,可以从第行获得该值$i结果如下:

$foo = $rv->{rows}[$i]->{my_column};

从数据库返回的行总数选择可以这样访问查询:

$nrows = $rv->{processed}

下面是一个使用不同命令类型的示例:

$query = "INSERT INTO my_table VALUES (1, 'test')";
$rv = spi_exec_query($query);

然后,您可以访问命令状态(例如。,SPI_OK_插入)像这样:

$res = $rv->{status};

要获得受影响的行数,请执行以下操作:

$nrows = $rv->{processed};

下面是一个完整的例子:

CREATE TABLE test (
    i int,
    v varchar
);

INSERT INTO test (i, v) VALUES (1, 'first line');
INSERT INTO test (i, v) VALUES (2, 'second line');
INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal');

CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
    my $rv = spi_exec_query('select i, v from test;');
    my $status = $rv->{status};
    my $nrows = $rv->{processed};
    foreach my $rn (0 .. $nrows - 1) {
        my $row = $rv->{rows}[$rn];
        $row->{i} += 200 if defined($row->{i});
        $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
        return_next($row);
    }
    return undef;
$$ LANGUAGE plperl;

SELECT * FROM test_munge();

spi_查询(*`command`*)
spi_fetchrow(*`cursor`*)
spi_cursor_close(*`cursor`*)

spi_查询斯皮乌·费特罗对于可能较大的行集,或者对于希望在行到达时返回行的情况,可以成对工作。斯皮乌·费特罗作品只有具有spi_查询.以下示例说明了如何将它们结合使用:

CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);

CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
    use Digest::MD5 qw(md5_hex);
    my $file = '/usr/share/dict/words';
    my $t = localtime;
    elog(NOTICE, "opening file $file at $t" );
    open my $fh, '<', $file # ooh, it's a file access!
        or elog(ERROR, "cannot open $file for reading: $!");
    my @words = <$fh>;
    close $fh;
    $t = localtime;
    elog(NOTICE, "closed file $file at $t");
    chomp(@words);
    my $row;
    my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
    while (defined ($row = spi_fetchrow($sth))) {
        return_next({
            the_num => $row->{a},
            the_text => md5_hex($words[rand @words])
        });
    }
    return;
$$ LANGUAGE plperlu;

SELECT * from lotsa_md5(500);

正常地斯皮乌·费特罗应该重复,直到它回来未定义,表示没有更多要读取的行。返回的游标spi_查询斯皮乌·费特罗返回未定义.如果您不想阅读所有行,请致电spi_光标_关闭释放光标。否则将导致内存泄漏。

spi_prepare(*`command`*,*`argument types`*)
spi_query_prepared(*`plan`*,*`arguments`*)
spi_exec_prepared(*`plan`*[,*`attributes`*],*`arguments`*]
spi_freeplan(*`plan`*)

准备好了吗, spi_查询_已准备好, spi_exec_已准备好spi_freeplan实现相同的功能,但用于准备好的查询。spi_prepare接受带有编号参数占位符($1、$2 等)的查询字符串和参数类型的字符串列表:

$plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2',
                                                     'INTEGER', 'TEXT');

一旦通过调用来准备查询计划spi_prepare,可以使用计划代替字符串查询,或者在spi_exec_prepared, 结果与返回的结果相同spi_exec_query,或在spi_query_prepared它返回一个完全一样的游标spi_query可以,以后可以传递给spi_fetchrow.可选的第二个参数spi_exec_prepared是属性的哈希引用;当前支持的唯一属性是限制,它设置查询返回的最大行数。

准备好的查询的优点是可以使用一个准备好的计划来执行多个查询。不再需要计划后,可以使用spi_freeplan

CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
        $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now',
                                        'INTERVAL');
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
        return spi_exec_prepared(
                $_SHARED{my_plan},
                $_[0]
        )->{rows}->[0]->{now};
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
        spi_freeplan( $_SHARED{my_plan});
        undef $_SHARED{my_plan};
$$ LANGUAGE plperl;

SELECT init();
SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
SELECT done();

  add_time  |  add_time  |  add_time
### 45.3.2. Utility Functions in PL/Perl

``elog(*`level`*, *`msg`*)`` []()

 Emit a log or error message. Possible levels are `DEBUG`, `LOG`, `INFO`, `NOTICE`, `WARNING`, and `ERROR`. `ERROR` raises an error condition; if this is not trapped by the surrounding Perl code, the error propagates out to the calling query, causing the current transaction or subtransaction to be aborted. This is effectively the same as the Perl `die` command. The other levels only generate messages of different priority levels. Whether messages of a particular priority are reported to the client, written to the server log, or both is controlled by the [log\_min\_messages](runtime-config-logging.html#GUC-LOG-MIN-MESSAGES) and [client\_min\_messages](runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES) configuration variables. See [Chapter 20](runtime-config.html) for more information.

``quote_literal(*`string`*)`` []()

 Return the given string suitably quoted to be used as a string literal in an SQL statement string. Embedded single-quotes and backslashes are properly doubled. Note that `quote_literal` returns undef on undef input; if the argument might be undef, `quote_nullable` is often more suitable.

``quote_nullable(*`string`*)`` []()

 Return the given string suitably quoted to be used as a string literal in an SQL statement string; or, if the argument is undef, return the unquoted string "NULL". Embedded single-quotes and backslashes are properly doubled.

``quote_ident(*`string`*)`` []()

 Return the given string suitably quoted to be used as an identifier in an SQL statement string. Quotes are added only if necessary (i.e., if the string contains non-identifier characters or would be case-folded). Embedded quotes are properly doubled.

``decode_bytea(*`string`*)`` []()

 Return the unescaped binary data represented by the contents of the given string, which should be `bytea` encoded.

``encode_bytea(*`string`*)`` []()

 Return the `bytea` encoded form of the binary data contents of the given string.

``encode_array_literal(*`array`*)`` []()   
``encode_array_literal(*`array`*, *`delimiter`*)``

 Returns the contents of the referenced array as a string in array literal format (see [Section 8.15.2](arrays.html#ARRAYS-INPUT)). Returns the argument value unaltered if it's not a reference to an array. The delimiter used between elements of the array literal defaults to "`, `" if a delimiter is not specified or is undef.

``encode_typed_literal(*`value`*, *`typename`*)`` []()

 Converts a Perl variable to the value of the data type passed as a second argument and returns a string representation of this value. Correctly handles nested arrays and values of composite types.

``encode_array_constructor(*`array`*)`` []()

 Returns the contents of the referenced array as a string in array constructor format (see [Section 4.2.12](sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS)). Individual values are quoted using `quote_nullable`. Returns the argument value, quoted using `quote_nullable`, if it's not a reference to an array.

``looks_like_number(*`string`*)`` []()

 Returns a true value if the content of the given string looks like a number, according to Perl, returns false otherwise. Returns undef if the argument is undef. Leading and trailing space is ignored. `Inf` and `Infinity` are regarded as numbers.

``is_array_ref(*`argument`*)`` []()

 Returns a true value if the given argument may be treated as an array reference, that is, if ref of the argument is `ARRAY` or `PostgreSQL::InServer::ARRAY`. Returns false otherwise.