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
Related
Can't figure out how to make mysql display the stored procedure result. Can't use table_name.column_name when calling the procedure. So the procedure doesn't know what table in the schema it should call? Trying to take an average of a numeric column called cateringID in a table called package. This table has NULL values several rows. Need to do this as a procedure. First converted all the NULLs values in cateringID field to numeric value of 0.0 in the procedure. Then took the resulting average of this field in the procedure. Then tried to call the procedure. But when trying to extract the average value of the cateringID field that is in the stored procedure, get NULL value?
DELIMITER //
CREATE PROCEDURE average_numeric_nulls(IN pPackageID INT, IN pCateringID DEC)
BEGIN
DECLARE pCateringID DECIMAL(5,4);
DECLARE catID DECIMAL(5,4);
SELECT IF(pCateringID IS NULL, 0.0000, FORMAT(pCateringID, 4))
INTO catID
FROM package
WHERE packageID = pPackageID;
SELECT(AVG(catID)) AS 'Replaced NULLS' FROM package;
END//
DELIMITER ;
CALL average_numeric_nulls(#packageID, #cateringID);
The pPackageID and pCateringID parameters represent the first two fields from an existing package table. ie.
pPackageID = packageID the PK in the package table. packageID is a numeric integer
pCateringID = cateringID the FK in the package table. cateringID is a mix of numeric integers and NULLs. Need to take the average of this column but must replace NULLs with 0.0 first.
So the procedure is supposed to read the value of the packageID from package table, pass this packageID value to the pPackageID variable in the procedure, then replace all pCateringID values if they are NULLs with the value 0.0000. So the average of the resulting cateringID column in the package table can be taken.
example package table
packageID cateringID packageName
001 NULL A
002 NULL B
003 001 C
004 002 D
005 003 E
Result ouput:
Replaced NULLS
NULL
So the procedure is supposed to read the value of the packageID from package table, pass this packageID value to the pPackageID variable in the procedure, then replace all pCateringID values if they are NULLs with the value 0.0000. So the average of the resulting cateringID column in the package table can be taken.
This can be performed by one single query:
SELECT FORMAT(AVG(COALESCE(cateringID, 0)), 4) AS avg_cateringID
FROM package
-- WHERE ...;
If you need to get average for some definite rows set then add according WHERE.
If you need to do it in SP form then
CREATE PROCEDURE average_numeric_nulls(IN pPackageID INT, IN pCateringID DEC)
SELECT FORMAT(AVG(COALESCE(cateringID, 0)), 4) AS avg_cateringID
FROM package
-- WHERE ...;
Use SP parameters in WHERE clause (or remove them if they not needed).
I am writing a stored procedure for mysql. I am using xampp localhost with mariadb.
The stored procedure receives an integer ID, and finds the string based on the ID frem the database. This string contains a list of numbers, seperated by commas.
I need to use this string of numbers for the IN clause in my SQL query.
CREATE PROCEDURE Test(IN id INT)
BEGIN
DECLARE clist VARCHAR(255);
SELECT clists INTO clist
FROM camp
WHERE cid = id ;
Now clist, a varchar variable contans a list of values like 4,6,8 in a string.
SELECT DISTINCT email
FROM table
WHERE ( col1 IN (clist) OR col2 IN (clist)
so in mysql, the query becomes like this, and fetches only a single ID of 4.
SELECT DISTINCT email
FROM table
WHERE ( col1 IN ('4,6,8') OR col2 IN ('4,6,8')
I want it to become
SELECT DISTINCT email
FROM table
WHERE ( col1 IN (4,6,8) OR col2 IN (4,6,8)
My question is - How do I remove the single quotes from the string?
Thanks.
It might be simplest (nastiest) to use FIND_IN_SET
WHERE FIND_IN_SET(col1, clist) > 0 OR FIND_IN_SET(col2, clist) > 0
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)
)
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')));
I have a settings table with two columns - name and value. Names are unique. I can easily read it into memory and then create a dictionary using the entry names as the keys.
I was wondering whether this can be done entirely from the SQL using some postgresql functions and applying the row_to_json function at the end.
I have version 9.2
Is it possible? It should be.
I think what you'd have to do is create a function for pulling a record in (as an argument) and transforming it to a record of arbitrary type and turning that into JSON.
This was done on 9.1 with the json extension.
create or replace function to_json(test) returns json language plpgsql
as $$
declare t_row record;
retval json;
begin
EXECUTE $E$ SELECT $1 AS $E$ || quote_ident($1.name) INTO t_row
USING $1.value;
RETURN row_to_json(t_row);
end;
$$;
Then I can:
select * from test;
name | value
-------+--------
test1 | foo
test2 | foobar
(2 rows)
SELECT to_json(test) from test;
to_json
--------------------
{"test1":"foo"}
{"test2":"foobar"}
Now if you want to merge these all into one object you have a little more work to do but it could be done using the same basic tools.
This should work in postgres-9.3. (untested, since I don't have 9.3 available here yet)
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE table pipo (name varchar NOT NULL PRIMARY KEY
, value varchar);
INSERT INTO pipo (name, value ) VALUES
('memory' , '10Mb'), ('disk' , '1Gb'), ('video' , '10Mpix/sec'), ('sound' , '100dB');
SELECT row_to_json( ROW(p.name,p.value) )
FROM pipo p ;