【问题标题】:PostgreSQL error 22P02 invalid input syntax for integerPostgreSQL 错误 22P02 整数的无效输入语法
【发布时间】:2013-01-17 18:30:50
【问题描述】:

我不断收到 22P02 错误:invalid input syntax for integer: "{1,2,3}"(请参阅服务电话中的评论)。

这是我的服务电话:

...
using (var command = new NpgsqlCommand("mediabase.create_media", connection))
{
    command.CommandType = System.Data.CommandType.StoredProcedure;
    command.Parameters.Add("title", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.title;
    command.Parameters.Add("uniqueFilename", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.uniqueFilename;
    command.Parameters.Add("description", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.description;
    command.Parameters.Add("categoryIds", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.categoryIds; /* here the value is "1,2,3" */
    command.Parameters.Add("typeId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.typeId;
    command.Parameters.Add("ownerId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.ownerId;
    command.Parameters.Add("statusId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.statusId;
    command.Parameters.Add("gpsLocation", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.gpsLocation;
    command.Parameters.Add("locationNameId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.locationId;
    command.Parameters.Add("uploadUserId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.uploadUserId;
    command.Parameters.Add("uploadDate", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.uploadDate;
    command.Parameters.Add("uploadIp", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.uploadIp;
    command.Parameters.Add("metadataId", NpgsqlTypes.NpgsqlDbType.Integer).Value = metadataId;
    command.Parameters.Add("sysEnvironment", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.sysEnvironment;
    command.Parameters.Add("languageId", NpgsqlTypes.NpgsqlDbType.Integer).Value = media.languageId;
    command.Parameters.Add("publicationIds", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.publicationIds;
    command.Parameters.Add("limitations", NpgsqlTypes.NpgsqlDbType.Varchar).Value = media.limitations;

    mediaId = Convert.ToInt32(command.ExecuteScalar());
}

pgTransaction.Commit();
...

还有存储过程:

CREATE OR REPLACE FUNCTION mediabase.create_media(
    title character varying, 
    uniquefilename character varying, 
    description character varying, 
    categoryids character varying, 
    typeid integer, 
    ownerid integer, 
    statusid integer, 
    gpslocation character varying, 
    locationnameid integer, 
    uploaduserid integer, 
    uploaddate character varying, 
    uploadip character varying, 
    metadataid integer, 
    sysenvironment character varying, 
    languageid integer, 
    publicationids character varying, 
    limitations character varying)
  RETURNS integer AS
$BODY$
    declare _mediaId integer;
    declare _point varchar;
    declare _gps_location geometry;
    declare _id text;

    begin

    IF (gpslocation <> '') THEN
      _point = 'POINT(' || gpslocation || ')';
      _gps_location = ST_Transform(ST_GeomFromText(_point, 4326), 900913);
    ELSE
      _gps_location = NULL;
    END IF;

    insert into mediabase.media (
        title, 
        unique_filename, 
        description, 
        owner_id, 
        status_id, 
        gps_location, 
        type_id, 
        location_name_id, 
        upload_user_id, 
        upload_date, 
        upload_ip, 
        metadata_id, 
        system_environment,
        language_id,
        limitations)

    values (
        title, 
        uniqueFilename, 
        description, 
        ownerId, 
        statusId, 
        _gps_location, 
        typeId, 
        locationNameId, 
        uploadUserId, 
        uploadDate, 
        uploadIp, 
        metadataId, 
        sysEnvironment,
        languageid,
        limitations)

    returning id into _mediaId; 

    -- insert category ids
    FOR _id IN SELECT string_to_array (categoryids,',')
    LOOP 
        INSERT into mediabase.media_categories (media_id, category_id)
        values (_mediaId, (_id::int));
    END LOOP;

    -- insert publication ids
    FOR _id IN SELECT string_to_array (publicationids,',')
    LOOP 
        INSERT into mediabase.media_publications (media_id, publication_id)
        values (_mediaId, (_id::int));
    END LOOP;

    return _mediaId;

    end;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

在service方法中可以看到,参数categoryids的输入是字符串"1,2,3"NpgsqlDbTypeVarchar。而在存储过程中,输入类型是character varying

这里是执行日志:

2013-01-17 08:56:42 CET ERROR:  invalid input syntax for integer: "{1,2,3}"
2013-01-17 08:56:42 CET CONTEXT:  SQL statement "INSERT into mediabase.media_categories (media_id, category_id)
            values (_mediaId, (_id::integer))"
    PL/pgSQL function "create_media" line 54 at SQL statement
2013-01-17 08:56:42 CET STATEMENT:  select * from mediabase.create_media(('Penguins')::varchar,('079117ec-676f-4022-9950-69e55c2a2600_Penguins.jpg')::varchar,('Description...')::varchar,('1,2,3')::varchar,(1)::int4,(1)::int4,(1)::int4,('')::varchar,(1)::int4,(1)::int4,('17/01/2013 08:56:42')::varchar,('::1')::varchar,(399)::int4,('dev')::varchar,(1)::int4,('1,2')::varchar,('Limitations...')::varchar)

为什么会弹出这个错误?

【问题讨论】:

  • 为什么不将characterids 定义为integer[]?然后您可以简单地省略所有演员表并使用generate_subscripts() 进行插入而不是循环。无论如何,string_to_array('{1,2,3}', ',') 的结果是 {"{1",2,"3}"}
  • @dezso 我更像是一个 C# 开发人员,而不是 SQL 鲨鱼。您能否添加一个示例代码来显示generate-subscripts() 的使用以及字符串的正确拆分。谢谢。
  • 您确定作为参数添加的media.categoryIds 是字符串1,2,3,而不是数组吗? {1,2,3} 是数组 [1,2,3] 的 PostgreSQL 表示,所以也许您正在传递一个数组,而 nPgSQL 正在为您转换它?否则,括号是从哪里来的?
  • @CraigRinger 是的,media.categoryIds 绝对是一个字符串。我实际上想用一个数组来做到这一点,但是在隐藏方面有问题。假设我正在发送一个整数数组,正如@dezso 所建议的那样:1)在服务方法中,应该与哪个NpgsqlDbType 一起发送? 2) 在存储过程端接收它的语法是什么?这样做可能会解决问题。
  • 能否请您在会话中启用log_statement = all,或在postgresql.conf 中全局启用,然后重新测试并编辑您的问题以显示nPgSQL 执行的S​​QL 语句的确切文本和确切文本错误消息,都取自 PostgreSQL 日志文件?

标签: postgresql stored-procedures


【解决方案1】:

我已经使用@dezso 和@CraigRinger 技巧解决了这个问题。我现在使用整数数组而不是逗号分隔的字符串。以下是更改:

在服务调用中:

...
/* media.categoryIds is of type int[] now */
command.Parameters.Add("categoryIds", NpgsqlTypes.NpgsqlDbType.Array | NpgsqlTypes.NpgsqlDbType.Integer).Value = media.categoryIds;
...

关于存储过程:

...
CREATE OR REPLACE FUNCTION mediabase.create_media(
    title character varying, 
    uniquefilename character varying, 
    description character varying, 
    categoryids integer[], -- changed type
    typeid integer, 
    ownerid integer, 
    statusid integer, 
    gpslocation character varying, 
    locationnameid integer, 
    uploaduserid integer, 
    uploaddate character varying, 
    uploadip character varying, 
    metadataid integer, 
    sysenvironment character varying, 
    languageid integer, 
    publicationids integer[], -- changed type
    limitations character varying)
...
...
    declare i integer;
...
...
    -- insert category ids
    FOR i IN SELECT generate_subscripts( categoryids, 1 )
    LOOP 
        INSERT into mediabase.media_categories (media_id, category_id)
        values (_mediaId, categoryids[i]);
    END LOOP;

    -- insert publication ids
    FOR i IN SELECT generate_subscripts( publicationids, 1 )
    LOOP 
        INSERT into mediabase.media_publications (media_id, publication_id)
        values (_mediaId, publicationids[i]);
    END LOOP;
...

再次感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多