I'm writing stored procedure that should search for records base on few procedure arguments.
The problem is that not always all arguments have to be passed, sometimes they may be set to NULL.
Is there a way to write sth that would work like that?
CREATE PROCEDURE testProc(IN p_idWorker INTEGER, IN p_idEffect INTEGER)
BEGIN
SELECT
*
FROM
CallHistory
WHERE
idWorker = IFNULL(p_idWorker, ANYTHING)
AND
idEffect = IFNULL(p_idEffect, ANYTHING);
END$$
Like so:
...
WHERE (p_idWorker IS NULL OR idWorkder = p_idWorker)
AND (p_idEffect IS NULL OR idEffect = p_idEffect);
Or, like the way you did, but instead of Anything use the column name instead like so:
...
WHERE
idWorker = IFNULL(p_idWorker, idWorker )
AND
idEffect = IFNULL(p_idEffect, idEffect );
You can use for example:
idWorker = IFNULL(p_idWorker, idWorker)
IF p_idWorker is null then this condition is always TRUE for all rows. If not then it is true only if idWorker = p_idWorker
First of all thank you Mahmoud and valex for your time but both answers are not totally good. They will not work if for example the field idWorker is nullable - it will not see the rows where field idWorker IS NULL.
The ultimate solution to this looks weird but it works:
...
WHERE
idWorker = IFNULL(p_idWorker, idWorker)
AND
IFNULL(ch.idProjTime, -1) = IFNULL(p_idProjTime, IFNULL(ch.idProjTime, -1))
Now it'll see NULL fields too.
If it is bad idea to sth like that (I can see probable performance impact - 3 times a row it does the IFNULL condition) - please correct me.
Related
I have a query where i have "TEST"."TABLE" LEFT JOINED to PUBLIC."SchemaKey". Now in my final select statement i have a case statement where i check if c."Type" = 'FOREIGN' then i want to grab a value from another table but the table name value i am using in that select statement is coming from the left joined table column value. I've tried multiple ways to get to work but i keep getting an error, although if i hard code the table name it seems to work. i need the table name to come from c."FullParentTableName". Is what i am trying to achieve possible in snowflake and is there a way to make this work ? any help would be appreciated !
SELECT
c."ParentColumn",
c."FullParentTableName",
a."new_value",
a."column_name"
CASE WHEN c."Type" = 'FOREIGN' THEN (SELECT "Name" FROM TABLE(c."FullParentTableName") WHERE "Id" = 'SOME_ID') ELSE null END "TestColumn" -- Need assistance on this line...
FROM "TEST"."TABLE" a
LEFT JOIN (
select s."Type", s."ParentSchema", s."ParentTable", s."ParentColumn", concat(s."ParentSchema",'.','"',s."ParentTable",'"') "FullParentTableName",s."ChildSchema", s."ChildTable", trim(s."ChildColumn",'"') "ChildColumn"
from PUBLIC."SchemaKey" as s
where s."Type" = 'FOREIGN'
and s."ChildTable" = 'SOMETABLENAME'
and "ChildSchema" = 'SOMESCHEMANAME'
) c
on a."column_name" = c."ChildColumn"
Thanks !
In Snowflake you cannot dynamically use the partial results as tables.
You can use a single bound value via identifier to bind a value to table name
But you could write a Snowflake Scripting but it would need to explicitly join the N tables. Thus if you N is fixed, you should just join those.
my php code (the only relevant part):
$sql="UPDATE `posts` SET `likes`=`likes`+1 WHERE `id`='$id'";
is not working. i am trying to increment an int which is by default set to zero. the variable id is correctly set (a response from an html form) and the insert function works perfectly in the next line. I've researched this for a few hours but have come up empty handed :\ was wondering if anyone could assist me or point me in the right direction of a possible solution.
this is my query executed in the next line:
$res= $mysqli->query($sql);
$mysql being the database connection and $sql being the code snippet above.
this is the table
The issue is the NULL allowance your table has for the integer column. I would recommend not using NULL on an integer column. For your current issue there are at least two ways to resolve it:
Use coalesce to select the value, or use 0 if it is null:
update posts
set likes = coalesce(likes, 0) + 1
where id = 10;
Demo: http://sqlfiddle.com/#!9/54d9ae/1
Update the row so it actually has a 0 value.
update posts
set likes = 0
where id = 10;
... or you could just set it to 1 with that update. With this approach though you can take off the where clause and correct the whole table, assuming the NULL was incorrect.
Address Table with 50 records. Has a bool field called "primary_address_indicator".
I want to update a selected record to true and automatically set all other 49 records to false.
I know I can do this with 2 sql statements
First (update all records to false)
UPDATE address SET address.primary_address_indicator=0
Then (update specific record to true)
UPDATE address SET address.primary_address_indicator=1 WHERE address.record_id=31
Is there a way to do this in a single sql statement? Something like #Rank?
Keeping it simple... no Unions or some weird self table join.
Maybe what I am looking for does not exist...and that is fine too. just curious.
Update with Case
UPDATE tableName
SET Pin = CASE
WHEN 1=1 --'your condition'
THEN True
ELSE False
END
PC : #keWalker
The simplest way is simply to treat the boolean result as a number:
UPDATE address a
SET a.primary_address_indicator = (a.record_id = 31);
CASE is the formal way to do it. This short-hand is specific to MySQL but it is one of the database-specific features that I like.
This is my first time creating a MySQL stored procedure and am stuck on getting the UPDATE piece to work correctly. The proc is performing an inner join, looking for matches on a domain name field. If there is a match, a column named inbound is getting updated with a value of 0. If there is not a match on the join, then I need inbound set to a value of 1.
When I run this, I am able to get the matches tagged with a 0, but the non-matches are not getting updated with a 1. I thought how I have the 'ELSE' part set up would take care of this- can anyone tell if I am missing something with the syntax?
CREATE PROCEDURE `sp_InboungTagging`()
BEGIN
update `tableA` a
inner join `TableD` d
on a.senderDomain = d.domainName
set inbound = CASE
when a.senderDomain = d.domainName then 0
ELSE 1
END
WHERE inbound is null;
END;|
DELIMITER ;
Thanks,
Ron
EDIT-
Thanks for your reply. I am looking for exact matches on a varchar field that has domain names in it- the master list of domains is in table D. If the record in TableA has a match in TableD, I want to tag that recored with a 0. If there is no match in TableD, then I would like to tag it with a 1. Let me know if that clears things up- thanks
Your JOIN condition is the same as your CASE condition. If you JOIN your two tables on:
a.senderDomain = d.domainName
Then there will be no values in the result set for which
a.senderDomain != d.domainName
so the ELSE clause of your CASE statement never fires.
Without knowing more about what you mean by "matches" and "non-matches," I can't really suggest a correction.
I have the following query, written inside perl script:
insert into #temp_table
select distinct bv.port,bv.sip,avg(bv.bv) bv, isnull(avg(bv.book_sum),0) book_sum,
avg(bv.book_tot) book_tot,
check_null = case when bv.book_sum = null then 0 else 1 end
from table_bv bv, table_group pge, table_master sm
where pge.a_p_g = '$val'
and pge.p_c = bv.port
and bv.r = '$r'
and bv.effective_date = '$date'
and sm.sip = bv.sip
query continued -- need help below (can some one help me make this efficient, or rewriting, I am thinking its wrong)
and ((sm.s_g = 'FE')OR(sm.s_g='CH')OR(sm.s_g='FX')
OR(sm.s_g='SH')OR(sm.s_g='FD')OR(sm.s_g='EY')
OR ((sm.s_t = 'TA' OR sm.s_t='ON')))
query continued below
group by bv.port,bv.sip
query ends
explanation: some $val that contain sip with
s_g ('FE','CH','FX','SH','FD','EY') and
s_t ('TA','ON') have book_sum as null. The temp_table does not take null values,
hence I am inserting them as zero ( isnull(avg(bv.book_sum),0) ) where ever it encounters a null for the following s_g and s_m ONLY.
I have tried making the query as follows but it made my script to stop wroking:
and sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or sm.s_t in ('TA','ON')`
I know this should be a comment, but I don't have the rep. To me, it looks like it's hanging because you lost your grouping at the end. I think it should be:
and (
sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or
sm.s_t in ('TA','ON')
)
Note the parentheses. Otherwise, you're asking for all of the earlier conditions, OR that sm.s_t is one of TA or ON, which is a much larger set than you're anticipating, which may cause it to spin.