วิธีการแปลง sql-text เป็น jsonb-string

Nov 23 2020

ดูเหมือนจะไม่มีวิธีที่ชัดเจน:

  • select 'a123'::text::jsonb= ข้อผิดพลาด: ไวยากรณ์การป้อนข้อมูลไม่ถูกต้องสำหรับประเภท json
  • select '"a123"'::text::jsonb= สตริง BADเพราะอ้าง
    การตรวจสอบselect '"a123"'::text::jsonb = ('{"x":"a123"}'::jsonb)->'x'
    จะเห็นว่าไม่ใช่ยกมาเป็นที่ถูกต้อง
  • select '123'::text::jsonb = ('{"x":123}'::jsonb)->'x';= ไม่ใช่สตริง

ฉันต้อง '123' และ 'A123' เป็นสตริง JSONb บริสุทธิ์


PS: มันเป็นไปไม่ซ้ำทั่วไปแปลงโดยอัตโนมัติอะไร

คำตอบ

1 ErwinBrandstetter Nov 23 2020 at 20:10

ในการแปลงลิเทอรัลสตริงที่ไม่ได้พิมพ์ซึ่งไม่ได้อยู่ในเครื่องหมายคำพูดคู่เป็นjsonb(หรือjson) ให้ใช้ฟังก์ชันto_jsonb()(หรือto_json()):

SELECT to_jsonb(text 'a123');

โปรดทราบว่าการป้อนข้อมูลจะต้องมีประเภทสตริง ( text, varchar, ... ), ไม่ได้เป็นตัวอักษร untyped นั่นเป็นวิธีที่ Postgres รู้ว่าคุณต้องการ JSON สตริง

ข้างต้นtext 'a123'เป็นวิธีหนึ่งในการโยนตัวอักษรที่ไม่ได้พิมพ์ มีคนอื่น ๆ :

  • แคสต์ประเภทข้อมูล Postgres

สำหรับการส่งโดยตรงไปยังjson(b)Postgres คาดว่าจะมีตัวอักษร JSON ที่ถูกต้อง (พร้อมด้วยสตริงที่ยกมาสองครั้ง):

SELECT '"a123"'::jsonb;  

หากต้องการแปลค่าแต่ละค่าเป็น JSON ดั้งเดิมคุณสามารถแคสต์ตามเงื่อนไขก่อนการแปลงได้ ตัวอย่าง:

SELECT p, CASE WHEN i>2 THEN to_jsonb(p::numeric) ELSE to_jsonb(p) END AS x
FROM   unnest('{ab,12,12,1.2}'::text[]) WITH ORDINALITY t(p,i);

select '"a123"'::text::jsonb = สตริง BAD เนื่องจากยกมา

เพื่อความแม่นยำผลลัพธ์ไม่ใช่สตริง แต่เป็นjsonbค่าที่มีสตริง JSON ในการรับสตริงเป็นชนิดข้อมูล Postgres textคุณต้องมี->>ตัวดำเนินการ:

select 'a123'::text  = ('{"x":"a123"}'::jsonb)->>'x'

หรือ (เปรียบเทียบค่า JSON):

select '"a123"'::jsonb = ('{"x":"a123"}'::jsonb)->'x';

ฉันต้องการ '123' และ 'a123' เป็นสตริง JSONb แท้

ดังนั้น:

SELECT '"123"'::jsonb, '"a123"'::jsonb;

ทั้งสองมี JSON สตริง

สิ่งนี้ยังใช้งานได้:

SELECT '123'::jsonb;

.. แต่มี JSON ตัวเลข

แต่ไม่ได้ผล:

SELECT 'a123'::jsonb;  -- error

.. เพราะไม่ใช่ลิเทอรัลตัวเลขที่ถูกต้อง

คู่มือนี้มีตารางการแมประหว่างJSON Primitive types และ Corresponding PostgreSQL types