Postgresql updating JSON column - sql

Running into an odd issue here that I hope you may be able to help me with.
I have a query as part of a set that I want to have update however when I run the query I always get
ERROR: invalid input syntax for type json
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1:
SQL state: 22P02
update attendee_data as t set
fname = c.attendee_fname,
lname = c.attendee_lname,
title = c.attendee_title,
email = c.attendee_email,
phone = c.attendee_phone,
company = c.attendee_company,
description = c.attendee_des,
links = CAST(c.attendee_links AS json),
grouplistid = c.attendee_groups,
attendeeonly = c.attendee_atonly
from (values (' Sandy1', 'Abbot', 'Sales Rep', '', '', '', '', '', '', '[{"test":"test"}]', '')) as c(attendee_fname,attendee_lname,attendee_title,attendee_email,attendee_phone,attendee_company,attendee_des,attendee_links,attendee_groups,attendee_atonly,attendee_id)
where CAST (c.attendee_id AS bigint) = CAST (t.sid AS bigint) AND aid = 91848 AND cid= 84616
The above query is test data running directly in PG admin, not sure what I'm doing wrong here but any help would be apreciated!
Thanks.

Related

How to do `UPDATE...SET...FROM` using knex?

What's the most terse way I can express an UPDATE...SET...FROM SQL statement using knex? This is what I've got currently:
const query =
knex('user_subscriptions').update(subscription).toQuery() +
knex.raw(
' from plans p where customer_id = ? and p.id = us.plan_id ' +
'returning us.*, p.name',
[customer_id]
);
The reason I'm doing this is that I want to efficiently return a field from a related table (JOIN style) without needing a separate query.
As instructed in the official site: knexjs.org/#Builder-update
knex('user_subscriptions')
.returning(['us.*', 'plans.name', 'customer_id'])
.where({
customer_id: '?',
plans.id: us.plan_id
})
.update({
subscription : '?
})
Does:
update `user_subscriptions` set `subscription ` = '?' where `customer_id` = '?' and 'plans.id' = 'us.plan_id'
Returns:
[ us.*: ..., plans.name: ..., customer_id: ... ]

Erlang ets:select sublist

Is there a way in Erlang to create a select query on ets table, which will get all the elements that contains the searched text?
ets:select(Table,
[{ %% Match spec for select query
{'_', #movie_data{genre = "Drama" ++ '_' , _ = '_'}}, % Match pattern
[], % Guard
['$_'] % Result
}]) ;
This code gives me only the data that started (=prefix) with the required text (text = "Drama"), but the problem is I need also the the results that contain the data, like this example:
#movie_data{genre = "Action, Drama" }
I tried to change the guard to something like that -
{'_', #movie_data{genre = '$1', _='_'}}, [string:str('$1', "Drama") > 0] ...
But the problem is that it isn't a qualified guard expression.
Thanks for the help!!
It's not possible. You need to design your data structure to be searchable by the guard expressions, for example:
-record(movie_data, {genre, name}).
-record(genre, {comedy, drama, action}).
example() ->
Table = ets:new('test', [{keypos,2}]),
ets:insert(Table, #movie_data{name = "Bean",
genre = #genre{comedy = true}}),
ets:insert(Table, #movie_data{name = "Magnolia",
genre = #genre{drama = true}}),
ets:insert(Table, #movie_data{name = "Fight Club",
genre = #genre{drama = true, action = true}}),
ets:select(Table,
[{#movie_data{genre = #genre{drama = true, _ = '_'}, _ = '_'},
[],
['$_']
}]).

Remove html tags from a column

I have the a column in my table which stores a paragraph like below :
<p>I like it.</p>this is my job.<main>current.</main>
I want to remove the tags <p>, </p>, and and all tags between < and >.
So my expected output will be like below :
I like it. this is my job. current.
please try this
DECLARE #txt NVARCHAR(MAX) = '<p>I like it.</p>this is my job.<main>current.</main>'
SELECT x.value('.', 'NVARCHAR(MAX)') FROM ( SELECT x =
CAST(REPLACE(REPLACE(#txt, '>', '/>'), '</', '<') AS XML) ) r
this will help to remove all tags
UPDATE: Samir's answer is better than mine as it can deal with html-crap
(as long as there is no < or > as normal content :-)
You can try this:
If your string is valid XML (meaning XHTML) you might go this route:
DECLARE #yourString NVARCHAR(100)=N'<p>I like it.</p>this is my job.<main>current.</main>';
SELECT CAST(#yourString AS XML).value('.','nvarchar(max)');
returns
I like it.this is my job.current.
Using . as the XPath will return the whole content as is...
Any invalid XML (very likely with simple html) will break this...
You can use giant REPLACE() :
SELECT REPLACE(REPLACE(REPLACE(REPLACE(col, '<p>', ''), '</p>', ''), '<main>, ''), '</main>', '')
If you are working the latest SQL version then this will be easy to write using TRANSLATE() :
SELECT TRANSLATE(col, '<p></p><main></main>', '')
If u want remove tags when select, you can do a normal SELECT and clear string:
SELECT column FROM my_table;
$value = $row["column"];
$value_replaced = str_replace('<p>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('</p>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('<main>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('</main>', '', $value);

Save array in DB when checked more than one checkbox

I have a problem greatest!! I guess that really want Array, look my console when I checked just one:
{"value_solve"=>["", "", "333", ""], "contract_number"=>["33"]}
-----
SQL (317.5ms) UPDATE "authorizations" SET "value_solve" = '', "situation" = 2 WHERE "authorizations"."contract_number" = ? [["contract_number", "33"]]
After, when I checked just one, the first:
{"value_solve"=>["111", "", "", ""], "contract_number"=>["11"]}
-----
SQL (317.5ms) UPDATE "authorizations" SET "value_solve" = '111 ', "situation" = 2 WHERE "authorizations"."contract_number" = ? [["contract_number", "11"]]
And, for last, when I just more then one:
{"contract_number"=>["11", "44"], "value_solve"=>["111", "", "", "444"]}
-----
SQL (297.7ms) UPDATE "authorizations" SET "value_solve" = '111', "situation" = 2 WHERE "authorizations"."contract_number" = ? [["contract_number", "11"]]
SQL (121.9ms) UPDATE "authorizations" SET "value_solve" = '', "situation" = 2 WHERE "authorizations"."contract_number" = ? [["contract_number", "44"]]
And this is my controller:
#selected_ids = params[:authorization][:contract_number]
#authorizations = Authorization.where("contract_number in (?)", #selected_ids)
auth_params = params[:authorization]
auth_params[:contract_number].zip(auth_params[:value_solve]).each do |contract_number, value_solve|
Authorization.where(contract_number: contract_number).update_all(value_solve: value_solve, situation: 2)
end
Just save the first value on DB, how I can save more then one value? Thanks!
As I understood, you want the contract_number with id 44 to be “associated” with value_solve == "444". If this is correct, you should remove blanks from your value_solve array:
auth_params[:contract_number].zip(auth_params[:value_solve].reject(&:blank?))...
Now 44 is being updated with the second element of value_solve, which is apparently an empty string.
See Array#zip for more details.

retrieving values from a result set ruby sqllite

I ran a query as follows:
rs = conn.execute("SELECT * FROM fruits WHERE name = 'apple' AND type = 'sweet'" )
puts "Results = #{rs.inspect}"
this gives me something like
Results = [{"fruitId"=> 123, "name"=>"apple", "type"=>"sweet" }]
How do I get the fruitId out from this?
I tried this:
puts "Retrieved fruitId = #{rs['fruitId'] }"
But that results in an error:
[] no implicit conversion of string to integer
How can I get the fruitId out?
Thanks
You're getting back an array, but you want a hash to be able to use rs['fruitId']. That's what its complaining about.
Try doing this:
db = SQLite3::Database.open "test.db"
db.results_as_hash = true
Source:
http://zetcode.com/db/sqliteruby/queries/
http://www.ruby-doc.org/core-2.0/Hash.html
Its an Array of Hashes. You can access fruitId of the first item in the Array like this
Results[0]["fruitId"]
#=> 123