How to reuse JSON arguments within PostgreSQL stored procedure - json

I am using a stored procedure to INSERT into and UPDATE a number of tables. Some of the data is derived from a JSON parameter.
Although I have successfully used json_to_recordset() to extract named data from the JSON parameter, I cannot figure how to use it in an UPDATE statement. Also, I need to use some items of data from the JSON parameter a number of times.
Q: Is there a way to use json_to_recordset() to extract named data to a temporary table to allow me to reuse the data items throughout my stored procedure? Maybe I should SELECT INTO variables within the stored procedure?
Q: Failing that can anyone please provide a simple example of how to update a table using data returned from json_to_recordset(). I must also include data not from the JSON parameter such as now()::timestamp(0).
This is how I have used json_to_recordset() so far:
INSERT INTO myRealTable (
rec_timestamp,
rec_data1,
rec_data2
)
SELECT
now()::timestamp(0),
x.data1,
x.data2
FROM json_to_recordset(json_parameter) x
(
json_data1 int,
json_data2 boolean
);
Thank you.

Related

Rails - How to reference model's own column value during update statement?

Is it possible to achieve something like this?
Suppose name and plural_name are fields of Animal's table.
Suppose pluralise_animal is a helper function which takes a string and returns its plural literal.
I cannot loop over the animal records for technical reasons.
This is just an example
Animal.update_all("plural_name = ?", pluralise_animal("I WANT THE ANIMAL NAME HERE, the `name` column's value"))
I want something similar to how you can use functions in MySQL while modifying column values. Is this out-of-scope or possible?
UPDATE animals SET plural_name = CONCAT(name, 's') -- just an example to explain what I mean by referencing a column. I'm aware of the problems in this example.
Thanks in advance
I cannot loop over the animal records for technical reasons.
Sorry, this cannot be done with this restriction.
If your pluralizing helper function is implemented in the client, then you have to fetch data values back to the client, pluralize them, and then post them back to the database.
If you want the UPDATE to run against a set of rows without fetching data values back to the client, then you must implement the pluralization logic in an SQL expression, or a stored function or something.
UPDATE statements run in the database engine. They cannot call functions in the client.
Use a ruby script to generate a SQL script that INSERTS the plural values into a temp table
File.open(filename, 'w') do |file|
file.puts "CREATE TEMPORARY TABLE pluralised_animals(id INT, plural varchar(50));"
file.puts "INSERT INTO pluralised_animals(id, plural) VALUES"
Animal.each.do |animal|
file.puts( "( #{animal.id}, #{pluralise_animal(animal.name)}),"
end
end
Note: replace the trailing comma(,) with a semicolon (;)
Then run the generated SQL script in the database to populate the temp table.
Finally run a SQL update statement in the database that joins the temp table to the main table...
UPDATE animals a
INNER JOIN pluralised_animals pa
ON a.id = pa.id
SET a.plural_name = pa.plural;

How to Map JSON data from a REST API to Azure SQL using Data Factory

I have a new pipeline in azure data factory.
I created the dataset, one from the rest api (a public one):
https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo
and then I created an azure sql table with columns shown in the screenshot
The problem, is that I dont know how to do the mapping, as this is a complex JSON object, I am limited with the Mapping Designer:
How do I map the date?
I tend to use an ELT approach for these, calling the REST API with a Web task and storing the JSON in a SQL table and then shredding the JSON using SQL functions like OPENJSON.
Example pipeline:
The key to getting this approach to work is the expression on the stored procedure parameter. This takes the whole JSON output from the Web task and passes it in to the proc. This is a simple logging proc which inserts the record into a logging table:
#string(activity('Web1').output)
I log to a table and then shred the JSON or you could use OPENJSON directly on the stored proc parameter, eg
--INSERT INTO ...
SELECT
CAST( [key] AS DATE ) AS timeSeriesDate,
JSON_VALUE ( x.[value], '$."1. open"' ) AS [open],
JSON_VALUE ( x.[value], '$."2. high"' ) AS [high],
JSON_VALUE ( x.[value], '$."3. low"' ) AS [low],
JSON_VALUE ( x.[value], '$."4. close"' ) AS [close],
JSON_VALUE ( x.[value], '$."5. volume"' ) AS [volume]
FROM dbo.myLog
CROSS APPLY OPENJSON(logDetails , '$."Time Series (Daily)"' ) x
--WHERE logId = 23333;
My results:
Does the data have a structure? If so, you can generate a dummy file, place it in sink and do a one time mapping. If not, you can Lookup on the file, iterate over the content in a For Each Loop Container and insert details on to a SQL table.
E.g.
insert <<your table>>
select '#item().name', '#item().address.city', #item().value
The important thing to remember is to iterate at the correct array. Let me know if it's not clear. Not in front of a system right now, so can't add screenshots.

How to get database sql values from an active record object?

My original problem is that I need to insert a lot of records to DB, so to speed up, I want to use mysqlimport which takes a file of row values and load them to specified table. So suppose I have model Book, I couldn't simply use book.attributes.values as one of the fields is a hash that is serialized to db (using serialize), so I need to know what is the format this hash will be stored in in the db. Same for time and dates fields. Any help?
How about using SQL insert statements instead of serialization?
book = Book.new(:title => 'Much Ado About Nothing', author: 'William Shakespeare')
sql = book.class.arel_table.create_insert
.tap { |im| im.insert(record.send(
:arel_attributes_with_values_for_create,
record.attribute_names)) }
.to_sql

Using parameters for stored procedures on MySQL

I'm trying to write a PL/SQL or T-SQL for the following example:
Write a PL/SQL or T-SQL procedure to retrieve and output the marina number, slip number, rental fee, boat name, and owner number for every slip whose length is equal to the length stored in I_LENGTH.
So far I've come up with this:
'Create Procedure Boat_Info (I_Length IN Marina_Slip.Length%Type) AS
I_Marina_Num Marina_Slip.Marina_Num%Type I_Slip_Num
Marina_Slip.Slip_Num%Type I_Rental_Fee Marina_Slip.Rental_Fee%Type
I_Boat_Name Marina_Slip.Boat_Name%Type I_Owner_Num
Marina_Slip.Owner_Num%Type;
Begin Select Marina_Num, Slip_Num, Rental_Fee, Boat_Name, Owner_Num
Into I_Marina_Num, I_Slip_Num, I_Rental_Fee, I_Boat_Name, I_Owner_Num
from Marina_Slip Where Length = ??
That last part I'm still missing, as I'm have no specific value for Length to restrict my output. and also cannot come up with a DBMS output.
The variable in paranthesis is a parameter. Yo can use it in your where clause.
For example :
(myLenght INT)
where length = myLength
You may define more than one parameters separated by a comma sign ,
See also: Mysql stored procedure parameters

Updating XML column with the new XML using parameterized stored procedure

This is something new for me to try using XML column in SQL server 2008 database. I have seen few posts related to this, but I am able to find it difficult.
Let me put my question in a simplest form.
I have a database table dbo.cXML that has the columns EmailID(nVarchar(128)), ClientID(int) and cycleXML(XML).
My middleware component implements complex business logic and spit out the XML after logic processing.
Now I have a requirement that need the following:
a) A stored procedure with parameters in place to perform a check on above table to see if there is already an XML for a given EmailID and Client ID. If a record exists, use Update query to update entire XML otherwise simply insert the XML.
b) A stored procedure whould be able to send back the complete XML to my middleware component on request.
Can someone please help me understand the pseudo code. Appreciate your help.
Thanks,
Yagya
Not totally sure what you mean by requirement 3b but does this help you???
IF EXISTS (SELECT 1 FROM dbo.cXML WHERE EmailID = #YourEmailID AND ClientID = #YourClientID)
BEGIN
UPDATE dbo.cXML
SET cycleXML = #YourXML
WHERE EmailID = #YourEmailID AND ClientID = #YourClientID
END
ELSE BEGIN
INSERT INTO dbo.cXML (EmailID, ClientID, cycleXML)
SELECT #YourEmailID, #YourClientID, #YourXML
END