Hi, I am trying to make and use a function that up...
# sql
l
Hi, I am trying to make and use a function that updates a jsonb field. However, I am having trouble using the variables inside the jsonb object.
Copy code
sql
CREATE OR REPLACE FUNCTION public.updateoffset(site text, offsetnumber integer, toscrape integer)
 RETURNS void
 LANGUAGE sql
AS $function$


 update settings set "offset" = coalesce("offset", '{}') || '{"$2": {"toscrape":$3}}'
  where site = $1;
$function$
calling it via:
Copy code
sql
SELECT * FROM public.updateoffset('test', 2, 2)
b
This part looks wrong to me:
coalesce("offset", '{}')
what is "offset" here? I don't see any variable called offset anywhere in the function.
l
The code itself works perfectly creating an object in the offset column or updating it if it exsist. So the "offset" part is fixed. I wan't the $2 exchanged with the variable "offsetnumber" and $3 with "toscrape"
The offset field will either be null or an object with one or more objects like this:
Copy code
{
  "100": {
    "toscrape": 103
  }
}
b
Ah, sorry, I missed that it's a column in your settings table? So are you getting an error message with this? Also, one thing I usually do is force the JSONB text to a JSONB type, i.e.
'{"$2": {"toscrape":$3}}'
to
'{"$2": {"toscrape":$3}}'::JSONB
I think in this case it's resolving to a string, and needs to be turned into JSONB. Not sure if typing it to JSONB like this will do that or if you'll need a function to convert text to JSONB here. Try the `::JSONB`first.
l
function itself works perfectly. I want the $2 and $3 changed to offsetnumber integer, toscrape integer
right now it errors because of the $3 - it expects either an int or a ' " '
Copy code
ERROR:  invalid input syntax for type json
LINE 7: ...ttings set "offset" = coalesce("offset", '{}') || '{"$2": {"...
                                                             ^
DETAIL:  Token "$" is invalid.
CONTEXT:  JSON data, line 1: {"$2": {"toscrape":$... 0.000 seconds. (Line 1).
I am searching for some way of interpolating the variable (both $2 and $3).
only $3 gives errors as it is not valid json
and $2 just inserts "$2" as string instead of the $2 value
b
maybe try :: to typecast those individual parts
$3 might need to be "$3"
l
Copy code
sql

  update settings
  set "offset" = 
    coalesce("offset", '{}') || format('{"%s": {"toscrape":%s}}', $2, $3)::jsonb
  where site = $1;
^^This worked perfectly!
b
interesting
2 Views