what's wrong with this bit of code - sql

declare
cursor c_pointage is select * from pointage;
v_pointage c_pointage%rowtype;
v_date nvarchar;
v_heures int ;
v_minutes int ;
begin
for v_pointage in c_pointage loop
v_date:= CONVERT(varchar(10), v_pointage.DateHeureArrivee, 120) ;
v_heures := DATEPART(hour, v_pointage.DateHeureArrivee);
v_minutes := DATEPART(minute, v_pointage.DateHeureArrivee);
insert into Calc_pointage values ( v_pointage.ID, v_pointage.Nom, v_pointage.Departement, v_pointage.NumCarte, v_pointage.IDterminale, v_pointage.NomTerminale, v_pointage.IDInOut,v_date,v_heures,v_minutes);
end loop;
end ;
i keep getting these errors :
Incorrect syntax near the keyword 'cursor'.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'v_pointage'.
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near 'loop'.
ps : the data type from the table i'm inserting from match the one i'm inserting into

You shouldn't be writing a cursor for this at all. INSERT ... SELECT should do the job:
insert into Calc_pointage (/*TODO - Column list */)
select
ID, Nom, Departement, NumCarte, IDterminale, NomTerminale, IDInOut,
CONVERT(varchar(10), DateHeureArrivee, 120), --Ideally, CONVERT(date,DateHeureArrivee) instead
DATEPART(hour, DateHeureArrivee),
DATEPART(minute, DateHeureArrivee)
FROM pointage
But now I look at this, this also smells distinctively of your having decided to break a process down into a series of procedural steps (why are you just copying one table into another?) when the whole thing should probably just be a CTE as part of a single set-based query.
A key thing to get your head aroung when transitioning to writing SQL is to "think in sets". Try not to break the problem down, or at least, don't break it down into loops and how to process a single row at a time. If your input data doesn't resemble what you want, think about how to transform the entire set of rows into a set of rows that more closely resembles what you're looking for. Then write a CTE that does that transformation, and build from there.

Related

How to combine If statement with Substring command in SQL?

I have two types of entries in one column. One type starts with V2, the other starts with a digit. How do I write a query in SQL where I can extract different part of the string based on how it starts?
TextStringColumn
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE
I wrote
SELECT TextStringColumn, If(TextStringColumn like 'V2%',SUBSTRING(TextStringColumn ,10,7),SUBSTRING(TextStringColumn ,1,7)) As NumberCol
FROM TestTable
But I keep getting syntax errors.
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'If'.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
The desired result will be
TextStringColumn NumberCol
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ 1000000
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE 2000308
You may use a CASE expression:
SELECT
CASE WHEN TextStringColumn LIKE 'V2%'
THEN SUBSTRING(TextStringColumn, 10, 7)
ELSE SUBSTRING(TextStringColumn, 1, 7) END AS NumberCol
FROM TestTable;
The above logic assumes the only two varieties of strings are those which start with V2, and those which do not start with V2.
If the strings are variable length ... consider a little JSON
Example
Declare #YourTable Table ([TextStringColumn] varchar(100)) Insert Into #YourTable Values
('V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ')
,('2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE')
Select A.*
,Val = case when [TextStringColumn] like 'V2%'
then JSON_VALUE(S,'$[2]')
else JSON_VALUE(S,'$[0]') end
From #YourTable A
Cross Apply ( values ( '["'+replace([TextStringColumn],'|','","')+'"]' ) ) B(S)
Returns
TextStringColumn Val
V2|T:GSK|1000000|S1:TES|S2:N/A|Q:24|S:0.5gx3|PD:2020-10-22|C:QQ 1000000
2000308|S1:BES|T:SKY|Q:16446G|BSI:BPKGVAXQOHZFWGE 2000308

How to test a condition in a sql case statement on numbers

I would like to substitute all the values that are greater or equal to 10 with an empty string with a SQL CASE statement on my Microsoft SQL Server 2017. However, I am getting an error that reads:
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near '>'.
Though there are some questions similar to my question, I can not find an answer that is specifically answering my question. For example this question here how to use > = condition in sql case statement?. I have also tried a dynamic query with a temporal table and this did not help.
Here is my code with the table definition and the test data as well as the actual query that I am running.
--table definition with two columns
declare #table table
(
person nvarchar(20),
digit decimal(10,2)
)
--insert test data with two records
insert into #table
select 'titimo', 9.51
union
select 'neriwo', 12.25
--the requirement is to not show the digit value if it is greater or equal to 10, but rather display an empty field.
--so, this is my select statement to meet this requirement that is failing
--with error message 'Incorrect syntax near >'
select
person,
case digit
when digit >= 10 then ''
else digit
end 'digit'
from #table
From my select statement above, I am expecting this output:
person digit
------ -----
titimo 9.51
neriwo
However, the output is not being generated because of the error message that I am experiencing.
You had a syntax error in your case. More over you cannot mix datatypes so you need to cast digit to varchar or change '' i.e. to null.
select
person,
case
when digit >= 10 then ''
else cast(digit as varchar(20))
end 'digit'
from #table
Your case is not formatted correctly - here's one option -
(also, you can't select text and numbers in the same column - so I casted your number to text... tweak to fit your needs)
select
person,
case when digit >=10 then ''
else CONVERT(VARCHAR(10), digit)
end 'digit'
from #table

Incorrect syntax near ',' SQL Server Error

I am having the following error on my SQL Server Query I don't know how to overcome it Because I tried my best Please help me getting out of it:
CREATE TABLE d3 as SELECT sessionnumber, sessioncount, LEFT(timespent, 1) , COUNT
as cnt
FROM clusters
GROUP BY 1, 2, 3
The following error is generated:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Please help me! Thanks in advance
This is not SQL Server syntax. You want select into:
SELECT sessionnumber, sessioncount, LEFT(timespent, 1) as TimeSpentCode, COUNT(*) as cnt
into d3
FROM clusters
GROUP BY sessionnumber, sessioncount, LEFT(timespent, 1);
All the columns need to have names. So I added one for the third column.
And, group by does not accept positional indicators in SQL Server, so I replaced them with the appropriate expressions.
You have the word count instead of count(something).

SQL date conversion for 8 char value with 00 as days

I have been having trouble trying to figure out how to properly convert the data. In its current form it is varchar and the data is as follows:
19260200,
19770900,
20030400,
20120300,
20020500,
So as you can see I have the year and months, but have no values for dates. When I try to insert it into SQL field formatted as datetime i get errors. Anyone know how i can fix this? I am working with a DB of 700,000 records so I need to be able to write some code to address it and not just manually go through and change.
Thanks in advance for the help!!!
INSERT dbo.destination(date_column)
SELECT dt FROM
(
SELECT dt = CASE
WHEN src_date_column LIKE '%00' THEN
STUFF(src_date_column, 8, 1, '1')
ELSE src_date_column
END
FROM dbo.source
) AS x
WHERE ISDATE(dt) = 1;
To address comments:
AS x is just an alias. A derived table needs to be called something. If you just say:
SELECT x FROM (SELECT x = 1);
You get this unhelpful error:
Msg 102, Level 15, State 1
Incorrect syntax near ';'.
But not if you say:
SELECT x FROM (SELECT x = 1) AS y;
As for your other question, you can simply add other columns to the inner SELECT, e.g.:
INSERT dbo.Citation(PatentNo, Citation, CitedBy, CitationDate)
SELECT PatentNo, Citation, WhoCitedThis, dt
FROM
(
SELECT PatentNo, CitationSource, WhoCitedThis, dt = CASE
WHEN CitationDate LIKE '%00' THEN STUFF(CitationDate, 8, 1, '1')
ELSE CitationDate
END
FROM dbo.CitationSource
) AS x
WHERE ISDATE(dt) = 1;
Now, you need to decide what you want to do with invalid dates, such as 20120231 or 20120399. Those are just left behind. My first recommendation would be to make that a proper date or datetime column, and reject bad dates from getting into the system in the first place.
You can try something like this:
cast(left(val, 6)+'01') as date)
That is, insert a valid day value into the string and do the conversion.

Inserting a resultset into a Table in Oracle

Heyho,
I've gotta write a Procedure which Inserts a resultset from a select-statement into a table.
A co-worker of mine did something similar before to copy values from one table to another. His statement looks like this:
CREATE OR REPLACE PROCEDURE Co-Worker(
pId IN INT
)
AS
BEGIN
INSERT INTO Table1_PROCESSED
SELECT * FROM Table1
WHERE ID = pId;
DELETE FROM Table1
WHERE ID = pId;
END Co-Worker;
/
The two tables mentioned here got the same structure (in fact table1_processed is just a copy of table 1).
So I thought like "Hey! I get a resultset from my select-satement too! So why I just don't adjust it a bit do to the same!"
So I created my Table like this:
MyTable:
TIMEID (number) | NAME (varchar2 - 128)
-----------------------------------
VALUE | VALUE
VALUE | VALUE
VALUE | VALUE
and my Procedure like this:
CREATE OR REPLACE procedure MyProcedure(
pdate in date,
pJobtype in number default 3,
pTasktype in number default 4,
pJobstatus in number default 1,
pTaskstatus in number default 4
)
AS
pformateddate date;
BEGIN
Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY')
into pformateddate
from dual;
Insert into MyTable (TIMEID, NAME)
Select Function_GETTIMEID(to_date(st, 'DD.MM.YYYY HH24')) TIMEID
,to_char(ext) NAME
from(
Select to_char(arch_job.exec_start, 'DD.MM.YYYY HH24') st
,file.name ext
, count(file.id) cnt
from
arch_task_file
left join file on arch_task_file.File_ID = file.ID
left join arch_task on arch_task_file.Task_ID = arch_task.ID
left join arch_job on arch_task.Job_ID = arch_job.ID
where
arch_job.exec_start > pformateddate
and arch_job.exec_end <pformateddate + 1
and arch_job.jobtype_id = pJobtype
and arch_job.jobstatus_id = pJobstatus
and arch_task.Tasktype_ID = pTasktype
and arch_task.Taskstatus_ID = pTaskstatus
group by
file.name,
to_char(arch_job.exec_start, 'DD.MM.YYYY HH24'
)
);
End MyProcedure;
/
the Result for the large Select-Statement ALONE looks like this:
TIMEID | NAME
-----------------------------------
VALUE | VALUE
VALUE | VALUE
VALUE | VALUE
But If I execute this procedure and give it a dummydate (sysdate - 12 or a date like '16.07.2010 10:32:50') my Toad-gives my a message "Procedure completed" my table stays empty...!
But as said before the large Select-Statement gives results so there shouldn't be a try to insert an empty resultset...! Can anyone tell me why my procedure ain't work?
Thx for every useful answer. =)
Greetz!
P.S.:
The
Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY')
into pformateddate
from dual;
is required to shorten the pDate-value! i tested it, so that works too and you can ignore it in the whole logic. It's just here to give you a complete picture of the situation!
This is a very common pattern in SQL forums. The pattern is the OP says
"I run this SQL in my TOAD worksheet
(or whatever) and it works. But when
I include it in a different context -
such as a stored procedure - it
doesn't work. What gives?"
What gives is that the two statements are not the same. Somewhere there is a mis-transcription. Perhaps a join has been omitted or an extra one added. The most likely source of errors is the replacement of literals in the worksheet with parameters in the stored procedure.
Obviously I cannot tell you where the difference lies. All I can do is urge you to closely inspect the two SQL statements and figure out the discrepancy.
If you really cannot find any difference then you will need to debug your code. The quickest way to start is with the Devil's Debugger. After the insert statement add this line:
dbms_output.put_line('Rows inserted = '||to_char(sql%rowcount));
You'll need to enable DBMS_OUTPUT in TOAD; there's a tab for it somewhere. This will at least tell you whether the query really is returning zero rows or your procedure is inserting rows and you're not seeing them for some reason. Those are two different problems.
You would need to COMMIT in the Toad session where you ran this procedure before you could see that data in the table in any other session, such as the table browser. Did you remember to do that?
Not really relevant to your problem but this
Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY')
into pformateddate
from dual;
is just a long winded way of removing the time element from the passed parameter. This does the same thing:
Select trunc(pdate)
into pformateddate
from dual;
Or indeed as Tony points out, a straightforward assignment:
pformateddate := trunc(pdate);