如何在pl / pgsql中使用自定义列名声明绑定游标

时间:2018-12-10 02:31:31

标签: postgresql plpgsql

我想在表名作为函数变量的函数中使用游标,一个简单的示例就是通过游标进行选择查询。

从PostgreSQL文档中,我发现我可以使用

int main()
{
    const char* filename = "input.svs";
    TIFF* tiff_in = TIFFOpen(filename, "r");
    TIFF* tiff_out = TIFFOpen("output.raw", "w");
    if (tiff_in) {
        uint32 imageWidth, imageLength;
        uint32 tileWidth, tileLength;
        uint32 tileCount, tileByteCounts;
        uint32 samplePerPixel, bitsPerSample;
        uint32 orientation, planarConfig, photoMetric;
        uint32 xResolution, yResolution;
        uint32 x, y;
        ttile_t tile;
        // get fileds from the input file
        TIFFGetField(tiff_in, TIFFTAG_IMAGEWIDTH, &imageWidth);
        TIFFGetField(tiff_in, TIFFTAG_IMAGELENGTH, &imageLength);
        TIFFGetField(tiff_in, TIFFTAG_TILEWIDTH, &tileWidth);
        TIFFGetField(tiff_in, TIFFTAG_TILELENGTH, &tileLength);
        TIFFGetField(tiff_in, TIFFTAG_SAMPLESPERPIXEL, &samplePerPixel);
        TIFFGetField(tiff_in, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
        TIFFGetField(tiff_in, TIFFTAG_TILEBYTECOUNTS, &tileByteCounts);
        TIFFGetField(tiff_in, TIFFTAG_ORIENTATION, &orientation);
        TIFFGetField(tiff_in, TIFFTAG_PLANARCONFIG, &planarConfig);
        TIFFGetField(tiff_in, TIFFTAG_PHOTOMETRIC, &photoMetric);
        TIFFGetField(tiff_in, TIFFTAG_XRESOLUTION, &xResolution);
        TIFFGetField(tiff_in, TIFFTAG_YRESOLUTION, &yResolution);

        // set files to the output file
        TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth);
        TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageLength);
        TIFFSetField(tiff_out, TIFFTAG_TILEWIDTH, tileWidth);
        TIFFSetField(tiff_out, TIFFTAG_TILELENGTH, tileLength);
        TIFFSetField(tiff_out, TIFFTAG_SAMPLESPERPIXEL, samplePerPixel);
        TIFFSetField(tiff_out, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
        TIFFSetField(tiff_out, TIFFTAG_PLANARCONFIG, planarConfig);
        TIFFSetField(tiff_out, TIFFTAG_PHOTOMETRIC, photoMetric);
        TIFFSetField(tiff_out, TIFFTAG_XRESOLUTION, xResolution);
        TIFFSetField(tiff_out, TIFFTAG_YRESOLUTION, yResolution);
        //TIFFSetField(tiff_out, TIFFTAG_ROWSPERSTRIP, 1);

        tdata_t buf = _TIFFmalloc(TIFFTileSize(tiff_in));
        for (int tile = 0; tile < TIFFNumberOfTiles(tiff_in); tile++)
        {
            TIFFReadRawTile(tiff_in, tile, buf, (tsize_t)-1);
            TIFFWriteRawTile(tiff_out, tile, buf, (tsize_t)sizeof(buf));
        }
        _TIFFfree(buf);
        TIFFClose(tiff_in);
        TIFFClose(tiff_out);
    }
    return 0;
}

但是当我输入

Declare curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;

它返回declare curs1 cursor (key integer) for execute 'select ' || quote_ident(colname) || ' from ' || quote_ident(tablename);

另一方面,如果我用ERROR: syntax error at or near "'select '"编写函数,如下所示:

refcursor

它将返回CREATE or replace FUNCTION cursor_hw(colname text,tablename text) RETURNS setof text AS $$ declare curs1 refcursor; BEGIN open curs1 for execute 'select ' || quote_ident(colname) || ' from ' || quote_ident(tablename); for x in curs1 loop return next x; end loop; END; $$ LANGUAGE plpgsql;

任何帮助将不胜感激,非常感谢!

1 个答案:

答案 0 :(得分:1)

对于动态SQL,您可能更喜欢使用简单的FOR record_variable IN EXECUTE <query>而不是OPEN FETCH

CREATE or replace FUNCTION cursor_hw(colname text,tablename text) 
RETURNS setof text  AS 
$$
DECLARE 
x RECORD;
BEGIN
  FOR x IN  execute  'select ' || quote_ident(colname) || ' from ' 
                               || quote_ident(tablename)
   LOOP
      IF x.first_name like 'D%' THEN
        RETURN NEXT x;
      END IF;
  END LOOP;
END; 
$$ LANGUAGE plpgsql;

执行

knayak=# select cursor_hw('first_name','employees');
 cursor_hw
-----------
 Donald
 Douglas
 David
 Diana
 Daniel
 Den
 David
 Danielle
 David
(9 rows)