I always have trouble attempting such. I found this as a solution, but I was curious if their was a better way of doing such.
declare #CountByZip as int
select #CountByZip = convert(decimal(18,4),count(HouseNumbers))
from zipcodeDB
Where zip is not null
And using this as the statement executes no problem!
Convert(decimal(18,4),Count(case when zip IN ('123', '456', '789') then zip else null end))/#CountByZip
However, I was curious if there was a way to convert to int in my case statement and allow that to remove the creation of the variable and select statement at the top of my example.
Convert(Bigint,Convert(decimal(18,4),Count(case when zip IN ('123', '456', '789') then zip else null end))/Count(Zip)
However, this returns the dreaded SQL error of
'Error converting data type varchar to numeric'
which is what made me switch to my declare statement at the top.
Is it possible to perform my 2nd example?
Try using something like this
cast(count(case when zip in ('123', '456', '789') then zip else null end)*1/whateveryourdividingby as decimal(10,4))
Related
Suppose that I have:
case
when #ID ='2386002' then ISNULL(nullif(i.call,''),i.standingOrderNumber)
when nullif(rtrim(i.call),'') is null then
nullif(rtrim(i.standingOrderNumber), '')
else case when nullif(rtrim(i.standingOrderNumber),'') is null then rtrim(i.call)
else
rtrim(i.call)
This is just a part of the procedure which does synchronization between two apps, the problem is that standingOrderNumber is not synchronized and I assume it has to to do with this code portion.
Scenario:
After entering call and standingOrderNumber like this:
call: '' (leave it empty)
standingOrderNumber: 777777
Data is stored in a table and procedure takes the data from that table and displays it on the app form, problem is, everything is displayed correctly, except for this standingOrderNumber.
Can you tell if something went wrong in the logic I submitted above ?
I think problem with the below line,
when #ID ='2386002' then ISNULL(nullif(i.call,''),i.standingOrderNumber)
here you are trying to check i.call for null value and replacing it with empty string and that makes ISNULL function useless.
Solution is not to use nullif in above line
I'll try and make this clear...
Let's say I have a table with 2 columns. issue_number and issue_text. I need to grab 2 strings out of the issue_text column. The first string is something that can be hard coded with case statements since there are only so many types of issues that can be logged (note, i know this isn't the best way)
case
when issue_text like '%error%' then 'error'
else 'not found'
end as error_type
the issue_text is a string that will be formatted mostly the same, it'll have an error, more info, then an incident number, and that is the end of the string.
i.e. "Can't add address. Ref Number: 9999999"
the problem I'm having is the number will not always be the same amount of characters away from the error message.
I was wondering if there is a way to access the substring that causes a match from the like clause. like another case statement using a regex(which i know aren't supported well in sql)
case
when issue_text like '%[0-9 .]%' then (the substring match from like '%[0-9 .]%')
else 00000
end as issue_number
I am restricted to solving this issue and parsing these strings from SQL Server Management Studio or yes, I'd use .net or something to leverage.
Declare #YourTable table (ID int,issue_text varchar(150))
Insert Into #YourTable values
(1,'Can''t add address. Ref Number: 9999999'),
(2,'error')
Select ID
,Issue = Left(issue_text,PatIndex('%:%',issue_text+':')-1)
,IssueNo = substring(issue_text,PatIndex('%:%',issue_text+':')+2,25)
From #YourTable
Returns
ID Issue IssueNo
1 Can't add address. Ref Number 9999999
2 error
If there's always a space just before the number and the number is the last part of the string you can do
RIGHT(issue_text, CHARINDEX(' ', REVERSE(issue_text)) - 1)
I'm trying to prepare a function, so I've started this sql sketch to figure out how to manage my situation:
DECLARE
x XMLType;
begin
x := XMLType('<?xml version="1.0"?>
<ROWSET>
<ROW>
<START_DATETIME>29/05/2015 14:23:00</START_DATETIME>
</ROW>
<ROW>
<START_DATETIME>29/05/2015 17:09:00</START_DATETIME>
</ROW>
</ROWSET>');
FOR r IN (
SELECT ExtractValue(Value(p),'/ROW/START_DATETIME/text()') as deleted
FROM TABLE(XMLSequence(Extract(x,'/ROWSET/ROW'))) p
) LOOP
-- do whatever you want with r.name, r.state, r.city
-- dbms_output.put_line( 'TO_DATE('''|| r.deleted ||''', '''|| 'DD/MM/YYYY HH24:MI:SS'')');
dbms_output.put_line( ''''|| r.deleted ||'''');
DELETE FROM MYTABLE a WHERE a.START_DATETIME not in (''''|| r.deleted || '''');
END LOOP;
END;
I've tried different ways to perform the query after the loop has filled the variable but is gaves me a conversion error:
00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
Can anybody help me?
thanks!
You're wrapping a string in explicit single quotes; that is making the quotes part of the string itself, which you don't want.
You need to convert the string to a data type, which you are sort of doing in a commented-out section - in that case you do need the extra quotes for your dbms_output() to make it a text literal, and to end up as a valid to_date() call; so you end up with output from that:
TO_DATE('29/05/2015 14:23:00', 'DD/MM/YYYY HH24:MI:SS')
But for your delete though you just need to do:
DELETE FROM MYTABLE a
WHERE a.START_DATETIME not in (to_date(r.deleted, 'DD/MM/YYYY HH24:MI:SS'));
The reference to r.deleted is already a string, so you refer to it directly, with no additional quotes.
You only have a single value though, so at that point in the loop using not in is not necessary and you can use != instead:
DELETE FROM MYTABLE
WHERE START_DATETIME != to_date(r.deleted, 'DD/MM/YYYY HH24:MI:SS');
Your title mentions an array, so perhaps you really intend to put all the values from the XML into a (schema-level type) table collection and then use that in the not in clause, so it removes everything except the dates in your XML. Doing it individually like this will effectively delete everything in the table if there is more than one date in the XML, which also suggests you either want to use an array, and/or actually meant in or = to only remove those.
Incidentally, extractValue() is deprecated, so it would be better to use XMLQuery or XMLTable, e.g.:
FOR r IN (
SELECT *
FROM XMLTable('/ROWSET/ROW/START_DATETIME'
PASSING x COLUMNS deleted VARCHAR2(19) PATH '.')
) LOOP
I want to use if else in where condition for Date Coulmns. Actually what i want to do is:
I have a table, which having two columns, CreatedDate and LastModifiedDate. Now what i want to check in Stored Proc is:
if LastUpdateDate is null then it will check for CreatedDate.
Below is my query:
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE SSA.UpdateDateTime IS NOT NULL
There are other number of table in joins i am just pasting the required query only. how can i go for the check i am totally confused.
Please help me..
UPDATED:
I have write the below code, please confirm if it is the correct way to use If in where
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE SSA.UpdateDateTime = ISNULL(SSA.UpdateDateTime,SSA.CreateDateTime)
I think i was not able to make my requirement very clear in first go, let me explain here..
i have a survey question answer table, i want to send an email notification if question has been answered, now answer can answered in one go, in that case createddate will have value not the updateddatetime,
Second case is:
answer is being updated in second go, then i need to check for the LastUpdateDateTime..
That's what i want to make in query.
You don't need any if / else functionality, just use the or operator to check that either is not null:
WHERE SSA.CreateDateTime is not null OR SSA.UpdateDateTime is not null
You can use COALESCE if you want this functionality, here are some sites for your reference.
http://www.mssqltips.com/sqlservertip/1521/the-many-uses-of-coalesce-in-sql-server/
http://sqlmag.com/t-sql/coalesce-vs-isnull
you can use case
SELECT Isnull(SSA.updatedatetime, Isnull(SSA.createdatetime, '')) AS
LastUpdateAnswerDateTime
FROM si_surveysiteanswer SSA
WHERE SSA.updatedatetime = CASE
WHEN SSA.updatedatetime IS NULL THEN
#SSA.createdatetime
ELSE SSA.updatedatetime
END
Try case statement.
SELECT isnull(SSA.UpdateDateTime,
isnull(SSA.CreateDateTime,'')) as LastUpdateAnswerDateTime
from SI_SurveySiteAnswer SSA
WHERE CASE WHEN SSA.UpdateDateTime IS NULL THEN SSA.CreateDateTime
ELSE SSA.UpdateDateTime END IS NOT NULL
i just created a java file to parse a csv files and saved them into an oracle database.. but i need a field ID which acts as a primary key.. and i am a bit confused abt looping..
I think all you need to do is utilize a sequence (as suggested by Ronnis)
as such
CREATE SEQUENCE FIELD_ID_SEQ START WITH 1 INCREMENT BY 1 NOCYCLE NOCACHE;
/*NOTE THE SEQUENCE, WHILE INCREMENTING, IS NOT GUARANTEED TO BE 1,2,3,4...N ->expect gaps in the #*/
Now either in your java app where you are saving the data:
"INSERT INTO TABLE_OF_CSV(FIELD_ID, FIELD_COLA, FIELD_COLB) VALUES(FIELD_ID_SEQ.NEXTVAL, ?,?);"
OR
Now if you are using a procedure (or a procedure within a package) you can do this (note this returns the primary key back to the calling app)
create procedure insertIntoCSVTable(pCOLA IN TABLE_OF_CSV.FIELD_COLA%TYPE
, pCOLB IN TABLE_OF_CSV.FIELD_COLB%TYPE
, pFIELD_ID OUT TABLE_OF_CSV.FIELD_ID%TYPE)
AS
BEGIN
INSERT INTO TABLE_OF_CSV(FIELD_ID, FIELD_COLA, FIELD_COLB)
VALUES(FIELD_ID_SEQ.NEXTVAL, pCOLA, pCOLB)
RETURNING FIELD_ID
INTO pFIELD_ID
;
END insertIntoCSVTable;
no looping required assuming you are already looping in your java code (assuming a row-by-row insert)
OR
You may use a trigger to insert a new value into the table:
create or replace
TRIGGER TABLE_OF_CSV_TRG BEFORE INSERT ON TABLE_OF_CSV
FOR EACH ROW
BEGIN
<<COLUMN_SEQUENCES>>
BEGIN
IF :NEW.FIELD_ID IS NULL THEN
SELECT FIELD_ID_SEQ.NEXTVAL INTO :NEW.FIELD_ID FROM DUAL;
END IF;
END COLUMN_SEQUENCES;
END;