Is it possible to pass multiple values to a parameter in Snowflake Table function?
For example, if we have country parameter - can we pass multiple values to the country and then use the parameter in the query using IN clause?
You can use an ARRAY to package multiple parameters into one, eg
SELECT ARRAY_CONSTRUCT('FR', 'IN', 'UK', 'NO') My_Multiparam_Array;
If you don't have scalar values, but eg. a table column, you have to construct the ARRAY with ARRAY_AGG().
Then use ARRAY_CONTAINS() instead of IN:
SELECT ARRAY_CONTAINS('FR'::VARIANT, My_Multiparam_Array); -- True if 'FR' is in the array
There are multiple ways that you could achieve this, here is the one that came to mind:
create or replace function get_ids(FirstNames Array)
returns table (id number)
as $$
select "CustomerKey"::Number
from dim_customer
where lower("FirstName") in (
select value from table(flatten(input=>FirstNames))
)
$$
;
select *
from table(get_ids(array_construct('jon', 'ruben', 'simon', 'shannon')));
Related
I have created a table in postgresql with column as jsonb
CREATE TABLE IF NOT EXISTS my_table ( data jsonb );
And I have inserted the values inside jsonb
INSERT INTO my_table ("data") VALUES ('{"id":"100100","my_array":[{"createdTime":1629686783,"updatedTime":1632365183,"status":"Initiated","my_array_id":"12345678"},{"createdTime":1627008383,"updatedTime":1627008383,"status":"Completed","my_array_id":"789010111"}]}');
How can I get inserted value using select query in PostgreSQL. I have used the below , but it is returning empty results
select *
from my_table
where (not data->'my_array' ??| array[cast('{"12345678"}' as varchar[])])
Kindly help
I assume that you are trying to get all records from 'my_table' where my_array_id is different from a certain value. In this case 12345678.
In any case, you need to use the jsonb_array_elements function in order to access the particular item from the array, and after that arrow '->>' in order to access the particular attribute from that item(json).
This is the query for the aforementioned assumption.
with temp_CTE as
(
select m.*,jsonb_array_elements(m.data->'my_array')->>'my_array_id' as my_array_id from my_table m
)
select * from temp_CTE c
where c.my_array_id<>'12345678'
I create a scalar function that calculates that multiplies the value of two columns and store that the result in a variable. That variable is returned. My objective is to use my function inside an insert statement in order to pupulate a field with the return value.
My problem is that when I call my function like so select calculate_price(4,5) I obtain the desired result. However, when I call the function inside the insert statement I get an unexpected result.
My code looks like so:
CREATE DEFINER=`root`#`localhost` FUNCTION `calculate_price`(idcart int, idProduct int) RETURNS int
DETERMINISTIC
BEGIN
select price*quantity into #price
from product inner join test_product_quantity_cart
on product.id_product=test_product_quantity_cart.id_product
where id_cart=idcart and test_product_quantity_cart.id_product=idProduct;
RETURN #price;
END
a row in my table test_product_quantity_cart looks like this:
id_cart=4
quantity=5
id_product=2
price_product= -- expected 20
the related row in my table product looks like so:
id_product=2
price=4
if I call my function this way select calculate_price(4,2), I get 20. Which makes sense because the price of product with id 2 is 4. The quantity is 5, so 4*5=20.
However, when I use the function inside a insert statement in order to create a new row like so:
insert into test_product_quantity_cart(id_cart,quantity,id_product,price_product )
values (4,5,2, calculate_price(4,2))
I get 45.
I would like to know what I am doing wrong that causes this inconsistente behavor.
Thank you for your help.
When you are doing the insert the db has not yet been written to when the function is invoked AND the function may find a preexisting row in test_product_quantity_cart so using the fiddle provided by akina and changing the first insert to 4/10/2 the second insert calculates a price of 40. Also the first insert does not acquire a price.
In my view a trigger would be more appropriate anyway.
I'm trying to filter the records with where clause in procedure based on IN input parameter values I had written the stored procedure in My SQL as like below :
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_get_logs_Test`(IN `p_Bot_Ids` VARCHAR(500))
NO SQL
select id, bot_id, log_level,log_type,time_stamp,finger_print,windows_identity,machine_name,process_name,process_version
,job_Id,robot_name,machine_Id,file_name,message,created_date from log
where id < 200 and
bot_id IN (p_Bot_Ids)$$
DELIMITER ;
My "p_Bot_Ids" is a comma separated string. If I pass "1,2" its filtering only with "1". if I pass "2,1" its filtering with only "2".
Also my "p_Bot_Ids" can also be null.In that case I needs to pull out all the records.
Let us consider there are 50 records in my table. If i pass "p_Bot_Ids" = "1,2,3" I needs to get only 1,2,3 Ids records(total 3 rows) only.
If I pass "p_Bot_Ids" = NULL then I should get all my 50 records.
What you are passing to the procedure is not a list: it is a comma-separated list, in other words a scalar value. So IN does not do what you expect: it actually checks if bot_id is equal to the parameter (this includes implicit conversion to the correct datatype).
If you are to keep the parameter as such, then one option is to use string function find_in_set() instead: its purpose is to search for a value in a comma-separated list.
where id < 200 and find_in_set(bot_id, p_Bot_Ids)
If you want to match on null values too, then:
where id < 200
and (
(bot_id is null and p_Bot_Ids is null)
or find_in_set(bot_id, p_Bot_Ids)
)
I pass value to store procedure. The logic is to split value by comma and using a loop.
#Colomns Id,Firstname,Lastname
#values 1,'foo','bar'
Query should be
Select * from user where Id = 1 and Firstname = 'foo' and Lastname = 'bar'
Just use substring_index() or concat():
Select *
from user
where concat_ws(Id, firstname, lastname) = #param;
Then, fix the stored procedure to take three parameters! There is no advantage to putting three values into a string, rather than passing in three separate values.
I have sql table with data as below
SnackID Name
1 Chicken
2 Soda
3 Chocolate
4 IceCream
I have the below user-defined function which accepts arguments as a string with multiple values like 'Chicken', 'Soda'.
CREATE FUNCTION GetSnackCodes
(
#myValues varchar(max)
)
RETURNS #SnacksCodes TABLE
(
mySnackCoded int NULL
)
AS
BEGIN
insert into #SnacksCodes
select SnackID from Snack where Name In (#myValues)
return ;
END;
GO
When I tried to invoke this function by passing multiple values to this variable I am not getting expected result.
I guess it's trying to search multiple (comma separated )values as a single value.
Any other possible workaround for how to pass this values?
Your guess is correct - when you pass a single string with comma-separated values, SQL server treats it as a single string value.
Use table valued parameter instead:
CREATE TYPE SnackCode As Table (
Name NVARCHAR(50)
);
GO;
CREATE FUNCTION GetSnackCodes (
#myValues SnackCode
)
RETURNS #SnacksCodes TABLE (
mySnackCoded int NULL
)
AS
BEGIN
insert into #SnacksCodes
select SnackID
from Snack
where Name In (select Name from #myValues)
return ;
END;
GO
you can split comma separated value and store that in temporary table then pass that table value result to query