using result scan of last statement in snowflake - snowflake-cloud-data-platform

Will there be any possible side effects with use of of the auto generated column from resultscan of last query_id

I couldn't understand how you will use the resultscan and last_query_id to fetch the generated column.
There is a method suggested by Marcin, which uses last_query_id and time travel:
https://stackoverflow.com/a/53903693/12550965
But it may generate an incorrect answer in rare situations.
If you need to get IDs (or any auto-increment column), I think you can use a sequence. You can read it before the INSERT, and then call the INSERT statement using the sequence value(s) manually.

No, not any downside or side-effects on using the result scan approach to retrieve the required information.

Related

SQL Server vector clock

Is there a global sequence number in SQL Server which guarantees to increment periodically (even when system time regresses), and can be accessed as part of an insert or update operation?
Yes the rowversion data type, and the ##dbts function are what you're looking for.
This pattern, of marking rows using a rowversion is implemented at a lower level by the Change Tracking feature. Which adds tracking of insert/updates and deletes, and doesn't require you to add a column to your table.
I'm pretty sure ROWVERSION does what you want. A ROWVERSION-typed column is guaranteed to be unique within any single database, and, per the SQL documentation, it is nothing more than an incrementing number. If you just save MAX(ROWVERSION) each time you've finished updated your data, you can find updated or inserted rows in your next update pass by looking fo0r ROWVERSIONs that are bigger than the saved MAX(). Note that you cannot catch deletes in this fashion!
Another approach is to use LineageId's and triggers. I'm happy to explain that approach if it would help, but I think ROWVERSION is a simpler solution.

Oracle - How to get last sequence value used in current session

I have a table in which the id column gets its value from a sequence.
I am interacting with database using OCI.
After inserting a record to the table, I need to get the value of the sequence which was used when inserting the record (into to my process memory), which effectively is the most recent sequence value generated for the current session. According to this answer, it should be possible.
I found USER_SEQUENCES table which may be suitable for my purpose, but I am not sure whether I can use it because it has sequence data about current user. What I need is sequence data of current session. I have multiple concurrent database sessions which use same user id and password.
you can make like this :
insert into testtable (ID, ...)
values (schema.seq_testtable.nextval, ...)
returning ID into currID;
you can read here about "returning" clause :
http://psoug.org/snippet/UPDATE-with-RETURNING-clause_604.htm
You can use sequence_name.currval . Oracle documentation says:
Using Sequence Numbers with CURRVAL
To use or refer to the current sequence value of your session,
reference seq_name.CURRVAL. CURRVAL can only be used if
seq_name.NEXTVAL has been referenced in the current user session (in
the current or a previous transaction). CURRVAL can be referenced as
many times as necessary, including multiple times within the same
statement. The next sequence number is not generated until NEXTVAL is
referenced.
You should specify which development environment are you using. If you use JAVA, when you have problem, because JDBC assumes what DML statements have ONLY input bind parameters. The common trick is to wrap an INSERT statement into anonymous block and make it callable statement.
begin
insert into t(id, x) valuse(t_seq.next_val, :x) returning in into :id;
end;
Such a callable statement will have one IN and one OUT parameter. Also JDBC 3.0 introduced it's own way ( getGeneratedKeys() method), but I'm not sure how it works with Oracle.
In case of OCI it works out-of-the-box. If I recall correctly in OCI you simply call OCIBindByName and you specify, that variable from returning clause is of type (INOUT). Then after execution you will find ID returned from a statement in that bind variable. It even works with bulk inserts, i.e you pass vector(s) of values to be inserted into the DB, and you get a vector of IDs generated.
I can not quickly find any OCI example. In case of OTL (OCI wrapper lib) it's here here. I think any OCI wrapper lib supports it. Also look at OCILIB, it's source code is easier to read.
SEQ_NAME.CURRVAL as per #Stefan said, but in that case you have 1st time you must have NEXTVAL for the same sequence in current session, in case of having CACHE in sequence you can use #EntGriff option of return inserted ID to variable.

Why does sql-server prevent inserting in WHEN MATCHED of merge?

Anyone know why sql server prevents inserting from within the WHEN MATCHED clause of a MERGE statement? I understand that the documentation only allows updates or deletes, I'm wondering why this is the case so I can understand merge better.
Look at this post for an example.
If you are trying to merge your source to your target, it does not make sense to insert a line if it was found in the target. You may want to update or delete it though. Inserting what is already there would create duplicates.
As you want to INSERT when you find a MATCH, i presume the condition of the ON-clause is met but another field is different. Consider including this field into the ON-clause with AND to differentiate between present rows and to be inserted rows.
Common sense says: if you already have it there (the record) why would you want to insert it again? Not to mention that normally the "matching" is on a non duplicated key.
If you are able to find a situation where a matched record needs to be inserted again, let us know to help you.
I think the case might be if I want to keep track of history. e.g. Telephone field; I want to see what was the telephone before you change it.

T-SQL Update Table using current columns as input parameters of function

I am trying to update table columns using a function. The input parameters of the function are data fields from the table that I want to update.
Let's say I have table with two columns ("Country" and "Capital"). The "Capital" is entered and I am using a function that returns a county name by capital name as input parameter. So, my update code is something like this:
UPDATE #TableName
SET Country=(SELECT Country FROM dbo.fn_GetCountryByCapital(Capital))
There is no error generated by IntelliSence,but on F5 press it say:
Incorrect syntax near 'Capital'.
Please, note that this is just a example (because it may looks to you silly). I give it sample in order to describe my problem. My real situation includes the use of several functions in the update statement.
Thank you in advance for the help.
Joro
Possible Solution:
I have found other way to do this. It does not look so good, but it works:
I have added index in my temp table in order to use while statement
For each record in the table (using while statement) I have used temp variables to store the field information I have need
Then I have passed this information to my functions and the outcome I have used to update the table
My guess is that the brackets '( )' that surrounded the select statement and the function do not allowed the function to use the correct values from the table.
learn the right way (most efficient) to build SQL:
UPDATE a
SET Country=b.Country
FROM #TableName a
INNER JOIN YourCountryCapitalTable b ON a.Capital=b.Capital
you can not code SQL like an application program, you need to use set logic and NOT per row logic. When you throw a bunch of functions into a SQL statement they most likely will need to be run per row, slowing down your queries (unless they are table functions in your FROM clause). If just incorporate the function into the query you can most likely see massive performance improvements because of index usage and operations occur on the complete and not row per row.
it is sad to have to very sql code that isn't elegant and often repeats itself all over the place. however, your main sql goal is fast data retrieval (index usage and set operations) and not some fancy coding beauty contest.
I have found other way to do this. yuck yuck yuck, sounds like a future question here on SO when the next person needs to maintain this code. You don't need an index to use a WHILE. If you have so many rows in your temp table that you need an index, a WHILE is the LAST thing you should be doing!

Postgresql: keep 2 sequences synchronized

Is there a way to keep 2 sequences synchronized in Postgres?
I mean if I have:
table_A_id_seq = 1
table_B_id_seq = 1
if I execute SELECT nextval('table_A_id_seq'::regclass)
I want that table_B_id_seq takes the same value of table_A_id_seq
and obviously it must be the same on the other side.
I need 2 different sequences because I have to hack some constraints I have in Django (and that I cannot solve there).
The two tables must be related in some way? I would encapsulate that relationship in a lookup table containing the sequence and then replace the two tables you expect to be handling with views that use the lookup table.
Just use one sequence for both tables. You can't keep them in sync unless you always sync them again and over again. Sequences are not transaction safe, they always roll forwards, never backwards, not even by ROLLBACK.
Edit: one sequence is also not going to work, doesn't give you the same number for both tables. Use a subquery to get the correct number and use just a single sequence for a single table. The other table has to use the subquery.
My first thought when seeing this is why do you really want to do this? This smells a little spoiled, kinda like milk does after being a few days expired.
What is the scenario that requires that these two seq stay at the same value?
Ignoring the "this seems a bit odd" feelings I'm getting in my stomach you could try this:
Put a trigger on table_a that does this on insert.
--set b seq to the value of a.
select setval('table_b_seq',currval('table_a_seq'));
The problem with this approach is that is assumes only a insert into table_a will change the table_a_seq value and nothing else will be incrementing table_a_seq. If you can live with that this may work in a really hackish fashion that I wouldn't release to production if it was my call.
If you really need this, to make it more robust make a single interface to increment table_a_seq such as a function. And only allow manipulation of table_a_seq via this function. That way there is one interface to increment table_a_seq and you should also put
select setval('table_b_seq',currval('table_a_seq')); into that function. That way no matter what, table_b_seq will always be set to be equal to table_a_seq. That means removing any grants to the users to table_a_seq and only granting them execute grant on the new function.
You could put an INSERT trigger on Table_A that executes some code that increases Table_B's sequence. Now, every time you insert a new row into Table_A, it will fire off that trigger.

Resources