How to skip column output based on value? - sql

I am using following script to generate objects in C# from Oracle and it works ok.
select 'yield return new Question { QuestionID = '||Q.questionid||', Qcode = "'||Q.Qcode||'", QuestionDescription = "'||Q.questiondescription||'", QuestionText = "'||Q.questiontext||'", QuestionCategoryId = '||Q.questioncategoryid||', QuestionTypeID = '||Q.QuestionTypeID||', IsThunderheadOnly = '|| case q.isthunderheadonly when 0 then 'false' else 'true' end ||', DisplayOrder = '||q.displayorder||' };'
from QUESTION q
where
questioncategoryid = 7
However again and again I run into the problem where I cannot || add columns with NULL values and solution to this point was adding those properties manually, which was ok when selecting up to 20 records.
Now I ran into a case of having to select hundreds of records and adding them manually would take substantial amount of time.
How could I modify the script to add (example) MaxValue property if column in the table is NOT NULL but skip it it if it is?

You can skip it with case ... when ... else like you figured out by yourself:
... ||case when A.NEXTQUESTIONID is not null then 'NextQuestionID = '||A.NEXTQUESTIONID||',' else '' end || ...
You can also use the nvl2 function for a shorter solution:
... || nvl2(A.NEXTQUESTIONID, 'NextQuestionID = '||A.NEXTQUESTIONID||',', '') || ...

Related

Using SELECT subquery in a CASE statement and handling NULLS

I have 2 SQL tables one holding stock information then a style table which details how the stock is used. For some jobs the information is contained with a print file so the value in the stock table would be BIN, if not it would contain a template name which would cause a query to a Styles table which then shows how the stock is used. There a 10 positions that a stock could be applied but the template table wouldn't have records for where a stock couldn't be used (on the back of a simplex job for example).
I have a stored procedure which works to provide the detail based on whether the logic value is BIN or not but for the records in the style table that have no value I get NULL back which I need to suppress but just putting ISNULL around the column name in the subquery isn't having any effect. Am I just missing something as I'd rather not nest in another CASE statement to check if the query would produce NULL
WITH STYLES AS
(
SELECT
#JOBNAME AS JobName, Logic AS StyleName
FROM
[dbo].[CON_Tbl_511_DigitalStocks]
WHERE
JOBNAME = #JOBNAME
)
SELECT TOP 1
[Logic],
[S1F], [S1B], [S2F], [S2B],
[S3F], [S3B], [S4F], [S4B],
[S5F], [S5B],
CASE
WHEN b.stylename = 'BIN'
THEN --checks if there is a style for this job
CASE
WHEN S1F = '' THEN ''
ELSE '1'
END -- if a stock code is specified then return the bin name ("1")
ELSE (SELECT PAGE
FROM [dbo].[CON_Tbl_512_DigitalLogic]
WHERE STYLENAME = B.StyleName
AND STOCKREF = 'S1F')
END AS S1F_LOGIC, -- If a style is used return the style instruction for this bin and side
CASE
WHEN b.stylename = 'BIN' -- repeat this for all bins/sides
THEN
CASE WHEN S1B = '' THEN ''
ELSE '1'
END
ELSE (SELECT PAGE
FROM [dbo].[CON_Tbl_512_DigitalLogic]
WHERE STYLENAME = B.StyleName AND STOCKREF = 'S1B')
END AS S1B_LOGIC,
CASE WHEN b.stylename = 'BIN' THEN
CASE WHEN S2F = '' THEN ''
ELSE '2' END
ELSE (SELECT PAGE FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F') END AS S2F_LOGIC -- this one returns NULL as there is no instruction required for "2SF"
FROM
[CON_Tbl_511_DigitalStocks] A
JOIN
STYLES B ON A.JOBNAME = B.JOBNAME
WHERE
A.JobName = #JobName
This code works fine until the last one as there is no value in the stockref column that says 'S2F' but putting SELECT ISNULL(PAGE, '') still returns NULL
Because this query is not finding any records:
SELECT PAGE FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F'
and you want it to return something, you can change it to:
SELECT coalesce(min(PAGE),'') FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F'
This will return the minimum value (min) of the found records, which will return NULL when noting found. The coalesce will turn this NULL into the empty string: ''
P.S.: see also SQL - Difference between COALESCE and ISNULL?

SQL : Update value when the value in the database is null

I know this is already asked question and possible to be close.
But i really want a answer, I already searched through the internet, Read documentations, Blogs, and Question to SO.
This is my Query so Far,
declare #count numeric
select #count = (select count(1) from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq))
update E496_TitleReference
set PrintStatus = '{0}',Is_AESM=isnull(-1,Is_AESM)
from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq)
if ##rowcount <> #count
begin
rollback tran
Print "Error: There is an error on table E496_TitleReference."
return
end
go
For eg, In my table in Database i have column name Is_AESM, In Is_AESM column it have 4 values.
Is_AESM
NULL
NULL
-1
-2
Something like this.
Now when i run my script, it has no problem when i run it,
Is_AESM=isnull(-1,Is_AESM)
In this query it will detect if Is_AESM is null, it will update Is_AESM = -1 if not it will retain the value.
Now my problem is, if my query detect Is_AESM has a null value, it will update all the value to -1.
Is_AESM
-1
-1
-1
-1
The result is something like that. Now i want is update only the null value not all the value in column Is_AESM.
I think this query is wrong Is_AESM=isnull(-1,Is_AESM).
Any ideas will be a big help.
You may try with coalsece() function
update E496_TitleReference
set PrintStatus = '{0}',Is_AESM=coalsece(Is_AESM,-1)
from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq)
you need to replace order of parameters.
Is_AESM=isnull(Is_AESM, -1)
You can use COALSECE function. It returns the first non-null entry from the given list. So:
Is_AESM= COALSECE(IS_AESM,-1)
This will return IS_AESM value if it is not null (since it is the first non-null value)
Else if IS_AESM is NULL then it returns -1 (since it is the non-null value)

firebird trigger string concatenation

anyone can help me with this. I created a trigger in firebird. I have this line that uses concatenation.
NEW.FIELDNAME = FIELD1 || FIELD2;
but it is not working, no record has been inserted. Is there any way for string concatenation? THANKS IN ADVANCE!
here is my full trigger
*query that initiate the variable PREV_STATUS:
SELECT FIRST 1 PREV_STATUSPERMINS FROM C3_EQUIPTSTATEPERMIN
WHERE TESTERID = NEW.TESTERID ORDER BY DATEMODIFIED DESC INTO :PREV_STATUS;
IF(PREV_STATUS IS NULL) THEN
BEGIN
NEW.PREV_STATUSPERMINS = '000';
END
ELSE
BEGIN
NEW.PREV_STATUSPERMINS = PREV_STATUS || NEW.STATUS;
END
You should use the "new" keyword to access the values of your fields within a trigger :
new.fieldname = new.field1 || new.field2;
Also, don't forget that if either of the fields is null, the concatenation will be null. If you want to avoid that, you could do something like this :
NEW.FIELDNAME = coalesce(new.FIELD1, '') || coalesce(new.FIELD2, '')

Conditional WHERE clause with CASE statement in Oracle

I'm brand-new to the Oracle world so this could be a softball. In working with an SSRS report, I'm passing in a string of states to a view. The twist is that the users could also pick a selection from the state list called "[ No Selection ]" ... (that part was not by doing and I'm stuck with implementing things this way)
If they choose the No Selection option, then I just want to return all states by default, otherwise return just the list of states that are in my comma-separated list.
This really seems like it should be easy but I'm stuck. Here is the code I have so far (just trying to get a sample to work) but my eyes have finally gone crossed trying to get it going.
Could anybody give me some direction on this one please?
begin
:stateCode:='MO,FL,TX';
--:stateCode:='[ No Selection ]';
end;
/
select count(*) as StateCount, :stateCode as SelectedVal
from hcp_state vw
where
(case
when (:stateCode = '') then (1)
when (:stateCode != '') then (vw.state_cd in (:stateCode))
(else 0)
end)
;
You can write the where clause as:
where (case when (:stateCode = '') then (1)
when (:stateCode != '') and (vw.state_cd in (:stateCode)) then 1
else 0)
end = 1;
Alternatively, remove the case entirely:
where (:stateCode = '') or
((:stateCode != '') and vw.state_cd in (:stateCode));
Or, even better:
where (:stateCode = '') or vw.state_cd in (:stateCode)
We can use a CASE statement in WHERE clause as:
SELECT employee_no, name, department_no
FROM emps
WHERE (CASE
WHEN :p_dept_no = 50 THEN 0
WHEN :p_dept_no = 70 THEN 0
ELSE -1
END) = 0;

Nhibernate Criteria Conditional Where

Im working on a NHibernate criteria wich i graduatly builds upp depending on input parameters.
I got some problem with the postal section of these paramters.
Since we got a 5 number digit zipcodes the input parameter is a int, but since we in database also accept foreign zipcodes the database saves it as string.
What im trying to replicate in NHibernate Criteria/Criterion is the following where clause.
WHERE
11182 <=
(case when this_.SendInformation = 0 AND dbo.IsInteger(this_.Zipcode) = 1 then
CAST(REPLACE(this_.Zipcode, ' ', '') AS int)
when this_.SendInformation = 1 AND dbo.IsInteger(this_.WorkZipcode) = 1 then
CAST(REPLACE(this_.WorkZipcode, ' ', '') AS int)
when this_.SendInformation = 2 AND dbo.IsInteger(this_.InvoiceZipcode) = 1 then
CAST(REPLACE(this_.InvoiceZipcode, ' ', '') AS int)
else
NULL
end)
What we do is to check where the member contact (this_) has preferenced to get information sent to, then we check the input zipcode as integer against three different columns depending on if the column is convertable to int (IsInteger(expr) function) if column is not convertable we mark the side as NULL
in this case we just check if the zipcode is >= input parameter (reversed in sql code since paramter is first), the goal is to do a between (2 clauses wrapped with 'AND' statement), >= or <=.
UPDATE
Got a hint of success.
Projections.SqlProjection("(CASE when SendInformation = 0 AND dbo.IsInteger(Zipcode) = 1 then CAST(REPLACE(Zipcode, ' ', '') AS int) when SendInformation = 1 AND dbo.IsInteger(WorkZipcode) = 1 then CAST(REPLACE(WorkZipcode, ' ', '') AS int) when SendInformation = 2 AND dbo.IsInteger(InvoiceZipcode) = 1 then CAST(REPLACE(InvoiceZipcode, ' ', '') AS int) else NULL END)"
, new[] { "SendInformation", "Zipcode", "WorkZipcode", "InvoiceZipcode" },
new[] { NHibernateUtil.Int32, NHibernateUtil.String, NHibernateUtil.String, NHibernateUtil.String });
Throw my whole clause in a Projections.SqlProjection, however when i run my code some of my projection is cut (" AS int) else NULL END)" is cut from the end) and makes the sql corrupt.
Is there some kind of limit on this ?
Got it working yesterday.
Projections.SqlProjection worked, however if you don't name the projection as a column it some how cuts some of the TSQL code.
(Case
when x = 1 then 'bla'
when x = 2 then 'bla_bla'
else NULL
END) as foo
when using the last part (as foo) and naming the entire case syntax it works and dont cut anything.
However i dont know why but i could not manage to use the aliases from the other part of the criteria.