How to use snowflake variables to insert data into a table - snowflake-cloud-data-platform

I'm trying to generalize a snowflake script with variables and currently stuck on how to use variables as column names to insert data into the table.
Here's what I'm trying to do.
Source table variables
set schem_name = 'schema';
set table_name = 'destination';
set s_var1 = 'source_col_1';
set s_var2 = 'source_col_2';
destination table variables
set d_var1 = 'dest_col_1';
set d_var2 = 'dest_col_2';
Now trying to insert into destination table
use schema identifier($schema_name);
below select statement works without issue.
select identifier($s_var1), identifier($s_var2)
from identifier($table_name);
But when trying to insert I keep getting errors.
This is what I tried.
insert into destination_table (identifier($d_var1), identifier($d_var2))
select identifier($s_var1), identifier($s_var2)
from identifier($table_name);

Related

prevent duplicate value to submit using stored procedure in sql server

I want to prevent the same #coupon_value in sp to submit and return
any message for validation using csharp but I am not able to how to
make changes in stored procedure.
CREATE PROCEDURE [dbo].[USP_REBATE_CAMPAIGN_RULE_DETAIL_VALIDATE]
#rebate_campaign_seq INT,
#coupon_value Varchar(50)='',
#Type varchar(50)='SERIES'
AS
SET NOCOUNT ON
BEGIN
SELECT rcrd.rebate_campaign_rule_detail_seq AS id,Type_value AS NAME,
'SERIES' AS type,
rcrd.amount_per_range AS Amount
FROM rebate_campaign_rule_detail rcrd (nolock)
INNER JOIN rebate_campaign_rule rcr
ON rcr.rebate_campaign_rule_seq = rcrd.rebate_campaign_rule_seq
INNER JOIN rebate_campaign rc
ON rc.rebate_campaign_seq = rcr.rebate_campaign_seq
WHERE rc.rebate_campaign_seq = #rebate_campaign_seq
AND rcrd.active_flag = 'Y' AND rcrd.type = #Type
AND rcrd.type_value=#coupon_value
End
The only way to prevent duplicate in database data is to add a UNIQUE CONSTRAINT. Everything else will fail, especially any solution coded with a procedural program, because of concurrency (imagine for a moment that two users launch the same procedure with the same values at the same time...).
To have a NULLbale UNIQUE constraint, you can add a UNIQUE filtered INDEX like this one :
CREATE INDEX X_UNIQUE_COUPON_RCRD
ON rebate_campaign_rule_detail (type_value)
WHERE type_value IS NOT NULL;

Insert into TABLE($TABLE_VARIABLE) snowflake

I am using snowflake
I am looking to insert data to a table while using a variable
The purpose of using the variable is so when I can change it without doing a find and replace all
CREATE OR REPLACE TABLE DB1.PUBLIC.HUMANS (
HUMAN VARCHAR(32)
)
;
The following works
INSERT INTO DB1.PUBLIC.HUMANS
SELECT 'SUCESS';
The following does not work
SET EXPORT_TABLE = 'DB1.PUBLIC.HUMANS';
INSERT INTO TABLE($EXPORT_TABLE)
SELECT 'FAILURE';
HOWEVER this works.
SELECT * FROM TABLE($EXPORT_TABLE);
Is there is a way to insert into a table defined by a table literal?
reference documentation:
https://docs.snowflake.com/en/sql-reference/literals-table.html
https://docs.snowflake.com/en/sql-reference/sql/insert.html
======================================================
Update: Answer found by comments below.
Thanks to Biraja Mohanty and Greg Pavlik
To make this work have to wrap the IDENTIFIER().
INSERT INTO IDENTIFIER($EXPORT_TABLE);
https://docs.snowflake.com/en/sql-reference/session-variables.html
SET EXPORT_TABLE = 'DB1.PUBLIC.HUMANS';
INSERT INTO identifier($EXPORT_TABLE)
SELECT 'FAILURE';

Concatenating a session variable in query syntax

I'd like to replace the database/schema definition directly in a query. Ideally, something like this (ignore the actual query, it's just fluff):
SET A_DBS = 'A_DATABASE.A_SCHEMA';
SET B_DBS = 'B_DATABASE.B_SCHEMA';
INSERT OVERWRITE INTO IDENTIFIER($B_DBS)."TABLE" SELECT * FROM IDENTIFIER($A_DBS)."TABLE";
The only way I've found to do this is also define a variable for each table. Such as:
SET A_TABLE = CONCAT($A_DBS, ',', 'TABLE');
SET B_TABLE = CONCAT($B_DBS, ',', 'TABLE');
INSERT OVERWRITE INTO IDENTIFIER($B_TABLE) SELECT * FROM IDENTIFIER($A_TABLE);
But I'd rather not do that, especially for queries with many tables. So...is what I'm looking for possible?

Looking for software that will help script update statements faster

I have a lot of mundane update statements I have to push through PLSQL and MSSQL and it requires a lot of editing. I will usually pull the data into excel than reformat it in notepad++ . This is pretty time consuming and I was wondering if there are any solutions for this?
UPDATE ATGSITES SET IPADDRESS = 'xxx' WHERE OWNSITEID = '270789'
UPDATE ATGSITES SET IPADDRESS = '1yyy' WHERE OWNSITEID = '270506'
UPDATE ATGSITES SET IPADDRESS = '158568' WHERE OWNSITEID = '27745'
X(35353) update statements
Perhaps you can create a table of updates and perform a single join
UPDATE ATGSITES SET IPADDRESS = B.IPADDRESS
From ATGSITES A
Join NewTable B on A.OWNSITEID = B.OWNSITEID
Where NewTable has the structure of OWNSITEID and IPADDRESS
I would also add an index on OWNSITEID
In Ms Sql Server
Save the data in a CSV text file delimited by comma like that format
IPADDRESS , OWNSITEID
xxx ,270789
1yyy ,270506
158568 ,27745
......
...........
suppose that the table to be updated is named: users_ip
Run the following script to update table from the text file
-- update table users_ip from csv file delimited wth , and first row is header
-- create temp table for loading the text file
CREATE TABLE #tmp_x (IPADDRESS nvarchar (10),OWNSITEID nvarchar(10))
go
-- import the csv file
BULK INSERT #tmp_x
FROM 'c:\temp\data.txt' --CSV file with header delimited by ,
WITH ( FIELDTERMINATOR =',',rowterminator = '\n',FIRSTROW = 2 )
go
update u
set u.IPADDRESS = t.IPADDRESS
from users_ip u
join #tmp_x t on t.OWNSITEID = u.OWNSITEID
//drop the temp table
drop table #tmp_x

Xml column attributes manipulation in sql server

I have a table named User in my database. In that there is a xml column named XmlText which contains lots of attributes.
<userDetails>
<MobileVerified>True</MobileVerified>
<EmailVerified>True</EmailVerified>
<IPAddress>122.160.65.232</IPAddress>
<Gender>Male</Gender>
<DateOfBirth>1970-03-22T00:00:00</DateOfBirth>
<DealingInProperties>residential_apartment_flat</DealingInProperties>
<DealingInProperties>residential_villa_bungalow</DealingInProperties>
<DealingInProperties>residential_farm_house</DealingInProperties>
</userDetails>
What is needed to do is i have to merge all the 'residential_villa_bungalow' values to 'residential_apartment_flat' if 'residential_apartment_flat' exists in the XmlText Column else 'residential_apartment_flat' will be left by default. There are approx 700000 record in the database so keep in mid that what technique can be used among normal update vs cursot.
Fire query with following columns "UserID,XmlText"
Probable logic wud be something like this..
if ('residential_villa_bungalow') exists
(
if ('residential_apartment_flat') exists
remove the 'residential_villa_bungalow' node as there must be only one 'residential_apartment_flat' node
else
update 'residential_villa_bungalow' into 'residential_apartment_flat'
)
XML Data Modification Language (XML DML)
-- Delete bungalow where already exist a flat
update YourTable
set XMLText.modify('delete /userDetails/DealingInProperties[. = "residential_villa_bungalow"] ')
where XMLText.exist('/userDetails[DealingInProperties = "residential_apartment_flat"]') = 1 and
XMLText.exist('/userDetails[DealingInProperties = "residential_villa_bungalow"]') = 1
-- Change value from bungalow to flat
update YourTable
set XMLText.modify('replace value of (/userDetails/DealingInProperties[. = "residential_villa_bungalow"]/text())[1]
with "residential_apartment_flat"')
where XMLText.exist('/userDetails[DealingInProperties = "residential_villa_bungalow"]') = 1

Resources