Recall stored case in TSQL - sql

I have a set of cases that I frequently use to categorize query results and rather than copy/pasting them from a saved file every time I'm hoping I can turn this simplified version of what I use..
CASE
WHEN source = 'x' AND othersource = 'y' THEN 'region'
WHEN subsource = 'm' AND othersubsource = 'n' THEN 'district'
WHEN littlesource = 'a' AND otherlittlesource = 'b' THEN 'office'
ELSE 'ERROR - LOOK AT ME'
END AS "Service Channel"
Into
#RDOCASE
Where #RDOCASE is a stored, short-form version of the full case I've listed above. I'm thinking it would be like declaring a variable at the beginning of a query except it's stored somewhere and can be recalled at any time in any query being run on this database.

You should let a computed column do the work for you . . . assuming that the columns all come from the same table:
ALTER TABLE t ADD ServiceChannel AS (<your case here>)
If the values come from multiple tables, then you can use a view for this purpose. Or perhaps a scalar function, if you want to pass in the relevant variables.
On a side note: don't use single quotes for column aliases. This is just confusing. Single quotes should be used for string and date constants.

Related

Can I use different selection comparisons based on a passed value in SQL?

I wasn't really sure of the best wording for the question but here is my dilemma:
I am passing a value to a sql query as #district. This value may be the exact district but it also has the possibility of being a value that should create a set of multiple districts. So if I pass 002 I want the WHERE clause to say I.Offense_Tract = #district. If I pass Other I want the WHERE clause to say I.Offense_Tract in (). What I am trying to do is something like:
AND
CASE
WHEN #district = "Other" THEN I.Offense_Tract in ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD')
ELSE I.Offense_Tract = #district
END
But this doesn't work. The problem, restated, is if the value passed is anything other than Other, I just want it to be =. If Other is passed, I want it to be IN.
You don't need the CASE expression.
You can apply this logic with operators AND and OR:
AND (
(#district = 'Other' AND I.Offense_Tract IN ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD'))
OR
(#district <> 'Other' AND I.Offense_Tract = #district)
)
Note that, in databases like MySql, Postgresql and SQLite, your code would work as it is.

How do I get around case sensitive fields when in SQL

My code is:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where party_type = :NEW.PARTY_TYPE
and identity = identity_
:NEW_PARTY_TYPE = 'SUPPLIER' while the value in the field is 'Supplier'. This code will pull back no records but if I change it to 'Supplier', it finds the record
How do I change to search with out matching the case?
You can convert both the variable and the field to upper or lower case.
where UPPER(party_type) = UPPER(:NEW.PARTY_TYPE)
This might cause a table space scan as the index on the field would be Case sensitive.
you can get around this by adding a generated column that is upper case and indexing that.
Change both of your values to upper case. Example:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where UPPER(party_type) = UPPER('SUPPLIER')
and identity = identity_
Besides converting both strings to the same case (upper- or lower-) and then comparing them for equality, most SQL dialects allow one to do a case-insensitive comparison by using the LIKE operator, as follows:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where party_type LIKE :NEW.PARTY_TYPE
and identity = identity_

Access update query using two tables

I am a novice when it comes to Access SQL - I have two tables, (Master and Extract) I need to update the Master table where the same Case exists (this is the unique key on both tables) but only if the Case Text is "NA".
UPDATE Master
SET ( 'Master.Date Closed' )
= (Date())
FROM Extract
WHERE ('Master.Case' = 'Extract.Case' AND 'Extract.Clarification Case Text' = "NA");
I am not sure how I get the Case ID into the query, how the structure would look etc.
So if the Case ID appears in both tables and the Clarification Case Text is "NA" then put today's date into Master.Date Closed.
Thanks for any help with this.
I think you intend this:
UPDATE Master
SET [Date Closed] = Date()
WHERE EXISTS (SELECT 1
FROM Extract
WHERE Master.Case = Extract.Case AND
Extract.[Clarification Case Text] = "NA"
);
Note: Only use single and double quotes for string and date constants. The escape character for field and column names is the square braces. Although other characters can be used, they tend to be confusing -- either to humans or to the SQL parser.

How to replace where clause dynamically in query (BIRT)?

In my report query I have a where clause that needs to be replaced dynamically based on the data chosen in the front end.
The query is something like :
where ?=?
I already have a code to replace the value - I created report parameter and linked to the value ? in the query.
Example:
where name=?
Any value of name that comes from front end replaces the ? in the where clause - this works fine.
But now I need to replace the entire clause (where ?=?). Should I create two parameters and link them to both the '?' ?
No, unfortunately most database engines do not allow to use a query parameter for handling a dynamic column name. This is for security considerations.
So you need to keep an arbitrary column name in the query:
where name=?
And then in "beforeOpen" script of the dataset replace 'name' with a report parameter value:
this.queryText=this.queryText.replace("name",params["myparameter"].value);
To prevent SQLIA i recommend to test the value of the parameter in this script. There are many ways to do this but a white list is the strongest test, for example:
var column=params["myparameter"].value;
if (column=="name" || column=="id" || column=="account" || column=="mycolumnname"){
this.queryText=this.queryText.replace("name",column);
}
In addition to Dominique's answer and your comment, then you'll just need a slightly more advanced logic.
For example, you could name your dynamic column-name-value pairs (column1, value1), (column2, value2) and so on. In the static text of the query, make sure to have bind variables for value1, value2 and so on (for example, with Oracle SQL, using the syntax
with params as (
select :value1 as value1,
:value2 as value2 ...
from dual
)
select ...
from params, my_table
where 1=1
and ... static conditions....
Then, in the beforeOpen script, append conditions to the query text in a loop as needed (the loop left as an exercise to the reader, and don't forget checking the column names for security reasons!):
this.queryText += " and " + column_name[i] + "= params.value" + i;
This way you can still use bind variables for the comparison values.

SQL - Conditionally joining two columns in same table into one

I am working with a table that contains two versions of stored information. To simplify it, one column contains the old description of a file run while another column contains the updated standard for displaying ran files. It gets more complicated in that the older column can have multiple standards within itself. The table:
Old Column New Column
Desc: LGX/101/rpt null
null Home
Print: LGX/234/rpt null
null Print
null Page
I need to combine the two columns into one, but I also need to delete the "Print: " and "Desc: " string from the beginning of the old column values. Any suggestions? Let me know if/when I'm forgetting something you need to know!
(I am writing in Cache SQL, but I'd just like a general approach to my problem, I can figure out the specifics past that.)
EDIT: the condition is that if substr(oldcol,1,5) = 'desc: ' then substr(oldcol,6)
else if substr(oldcol,1,6) = 'print: ' then substr(oldcol,7) etc. So as to take out the "desc: " and the "print: " to sanitize the data somewhat.
EDIT2: I want to make the table look like this:
Col
LGX/101/rpt
Home
LGX/234/rpt
Print
Page
It's difficult to understand what you are looking for exactly. Does the above represent before/after, or both columns that need combining/merging.
My guess is that COALESCE might be able to help you. It takes a bunch of parameters and returns the first non NULL.
It looks like you're wanting to grab values from new if old is NULL and old if new is null. To do that you can use a case statement in your SQL. I know CASE statements are supported by MySQL, I'm not sure if they'll help you here.
SELECT (CASE WHEN old_col IS NULL THEN new_col ELSE old_col END) as val FROM table_name
This will grab new_col if old_col is NULL, otherwise it will grab old_col.
You can remove the Print: and Desc: by using a combination of CharIndex and Substring functions. Here it goes
SELECT CASE WHEN CHARINDEX(':',COALESCE(OldCol,NewCol)) > 0 THEN
SUBSTRING(COALESCE(OldCol,NewCol),CHARINDEX(':',COALESCE(OldCol,NewCol))+1,8000)
ELSE
COALESCE(OldCol,NewCol)
END AS Newcolvalue
FROM [SchemaName].[TableName]
The Charindex gives the position of the character/string you are searching for.
So you get the position of ":" in the computed column(Coalesce part) and pass that value to the substring function. Then add +1 to the position which indicates the substring function to get the part after the ":". Now you have a string without "Desc:" and "Print:".
Hope this helps.