You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ODB中PostgreSQL NUMERIC映射C++ int的value_trait报错排查

问题原因

你实现的value_trait<int, id_numeric>存在核心错误:PostgreSQL的NUMERIC类型在ODB参数传递中采用文本格式(字符串形式),而非二进制int的内存表示。你直接用memcpy将int的二进制值写入buffer,数据库收到的是无法解析的二进制数据,因此判定数据长度不足,抛出08P01错误。

修正后的value_trait实现

正确的处理逻辑是:在set_image中将int转换为字符串,把字符串的字节内容写入buffer;在set_value中将buffer中的字符串转换回int:

namespace odb {
    namespace pgsql {
        template <>
        struct value_traits<int, id_numeric>
        {
            using image_type = details::buffer;
            using query_type = int;

            static void set_image(image_type& image, std::size_t& size, bool& is_null, const int& value)
            {
                is_null = false;
                std::string s = std::to_string(value);
                size = s.size(); // 使用字符串实际长度作为数据大小

                if (size > image.capacity()) {
                    image.capacity(size);
                }
                
                std::memcpy(image.data(), s.data(), size); // 拷贝字符串的字节内容
            }

            static void set_value(int& value, const image_type& image, std::size_t size, bool is_null)
            {
                if (is_null)
                {
                    value = 0;
                    return;
                }

                try
                {
                    // 将buffer字节转为字符串,再转换为int
                    std::string s(image.data(), size);
                    value = std::stoi(s);
                }
                catch (const std::exception& e)
                {
                    throw std::runtime_error("Failed to convert NUMERIC to int: " + std::string(e.what()));
                }
            }
        };
    }
}
额外注意事项
  • 确保PersonId类正确映射(name, birthday)复合主键,ODB能正常将其序列化为数据库主键字段。
  • 由于NUMERIC(3)的取值范围是-999到999,远小于int的默认范围,可在set_image中添加范围检查,避免插入超出字段限制的值。

内容的提问来源于stack exchange,提问作者PietFisch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:22:09