Reputation: 1
I'm trying to use insert into() and values() based on an existing condition in my original table to create a new table. I do have working code that uses insert into() along with a select and where clause but I'm trying to see if it's possible to do a CASE WHEN statement outside of the values so that certain values are inserted into the new table based on a conditional.
-- Creation and inserting values into table invoice_original
create temporary table invoice_original (id integer, price number(12,2),
purpose varchar);
insert into invoice_original (id, price, purpose) values
(1, 11.11, 'Business'),
(2, 22.22, 'Personal'),
(3, 33.33, 'Business'),
(4, 44.44, 'Personal'),
(5, 55.55, 'Business');
-- Creates final empty table invoice_final
create temporary table invoice_final (
study_number varchar,
price number(12, 2),
price_type varchar
);
Code:
execute immediate $$
declare
new_price number(12,2);
new_purpose varchar;
c1 cursor for select price, purpose from invoice_original;
begin
for record in c1 do
new_price := record.price;
new_purpose := record.purpose;
-- This code runs!
insert into invoice_final(study_number, price, price_type)
select 1, :new_price, 'Dollars'
where :new_purpose ilike '%Business%';
insert into invoice_final(study_number, price, price_type)
select 2, :new_price, 'Dollars'
where :new_purpose not like '%Business%';
-- Does not run but this is what I'm trying to do instead
CASE
WHEN :new_purpose ilike '%Business%' then
insert into invoice_final(study_number, price, price_type)
values('1', :new_price, 'Dollars')
ELSE
insert into invoice_final(study_number, price, price_type)
values('2', :new_price, 'Dollars') END
end for;
end;
$$;
This is just a simplified example of what I'm trying to do as whole, but just really wondering if a case when insert into() values() is possible in this scenario.
Upvotes: 0
Views: 1314
Reputation: 25903
I will write some example code soon.
But the form
INSERT INTO (SELECT FROM VALUES WHERE)
Allows all your N value lines to be present. And the CASE logic to be in the WHERE and the result SUB-SELECT is INSERTed.
The ofther option if you are in Snowflake Scripting is to use an IF around those INSERTS verse using a CASE
What I was meaning, done with "full SQL variables as my example is not part of a loop" is you can move the SQL around like so, and have one block:
create temporary table invoice_final (
study_number varchar,
price number(12, 2),
price_type varchar
);
set new_purpose = 'Business';
set new_price = 10.0::number(12, 2);
insert into invoice_final(study_number, price, price_type)
SELECT column1, column2, column3
FROM VALUES
('1', $new_price, 'Dollars'),
('2', $new_price, 'Dollars')
WHERE CASE WHEN $new_purpose ilike '%Business%' then '1' ELSE '2' END = column1;
Thus for you loop, the three $
would be replaced with :
, but this inserts just one row.
the IF was meaning are the Snowflake Scripting IF, but there is examples of using CASE just below that also.
Upvotes: 0
Reputation: 175556
The CASE statement is allowed as branching construct:
Changes:
a) using INSERT INTO SELECT
b) each statement must end with ;
execute immediate $$
declare
new_price number(12,2);
new_purpose varchar;
c1 cursor for select price, purpose from invoice_original;
begin
for record in c1 do
new_price := record.price;
new_purpose := record.purpose;
CASE
WHEN :new_purpose ILIKE'%Business%' THEN
INSERT INTO invoice_final(study_number, price, price_type)
SELECT '1', :new_price, 'Dollars';
ELSE
INSERT INTO invoice_final(study_number, price, price_type)
SELECT '2', :new_price, 'Dollars';
END CASE;
end for;
end;
$$;
Disclaimer: Using cursor loop and loop in general should be used when there is no way of rewriting the code to set-based approach.
INSERT INTO invoce_final(study_number, price, price_type)
SELECT CASE WHEN purpose ILIKE'%Business%' THEN 1 ELSE 2 END,
price,
'Dollars'
FROM invoice_orginal;
Upvotes: 1
Reputation: 2746
You need to use INSERT ALL
. Refer here for more.
Change code as below
execute immediate $$
declare
new_price number(12,2);
new_purpose varchar;
c1 cursor for select price, purpose from invoice_original;
begin
for record in c1 do
new_price := record.price;
new_purpose := record.purpose;
INSERT ALL
when npurpose ilike '%Business%' then
into invoice_final(study_number, price, price_type)
values ('1',nprice,'Dollars')
else
into invoice_final(study_number, price, price_type)
values('2',nprice,'Dollars')
select :new_price as nprice, :new_purpose as npurpose;
end for;
end;
$$;
Executing above will produce following result -
select * from INVOICE_FINAL;
STUDY_NUMBER | PRICE | PRICE_TYPE |
---|---|---|
1 | 11 | Dollars |
2 | 22 | Dollars |
1 | 33 | Dollars |
2 | 44 | Dollars |
1 | 56 | Dollars |
Upvotes: 1