SQL conversion error because of datetime2 - sql-server

I have a view in a SQL Server 2008 database that has a datetime2 field. I need to be able to query from that view via a linked SQL server 2005. When I run open my cursor and fetch the records I get a "Conversion failed when converting datetime from character string." error. How do I make the cursor convert the datetime2 appropriately?
Here is my query that is failing
DECLARE #time DateTime
DECLARE db_cursor CURSOR FOR
SELECT [DateTime] FROM [LINKEDSERVER].[DATABASENAME].[dbo].[ViewName]
WHERE Name = 'blah'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #time
WHILE ##FETCH_STATUS = 0
BEGIN
Print #time
FETCH NEXT FROM db_cursor INTO #time
END
CLOSE db_cursor
DEALLOCATE db_cursor
Any ideas?

try to declare cursor in following way:
DECLARE db_cursor CURSOR FOR
SELECT cast([DateTime] as DateTime) FROM [LINKEDSERVER].[DATABASENAME].[dbo].[ViewName]
WHERE Name = 'blah'
BUT
if remote values from DATETIME2 field is outside the allowed to DateTime type, then try the following
DECLARE #time NVARCHAR(100)
DECLARE db_cursor CURSOR FOR
SELECT CAST([DateTime] as NVArCHAR(100)) FROM [LINKEDSERVER].[DATABASENAME].[dbo].[ViewName]
WHERE Name = 'blah'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #time
WHILE ##FETCH_STATUS = 0
BEGIN
Print #time
FETCH NEXT FROM db_cursor INTO #time
END
CLOSE db_cursor
DEALLOCATE db_cursor

Related

Incorrect Syntax Near Cursor

I have written the below code and it throws an error as 'Incorrect Syntax near mycursor'. Can anyone let me know what am I doing wrong?
SELECT DISTINCT [FILE_NAME] INTO #TEMP FROM [dbo].[ABI_IND_STR_PLAN_DAILY] WHERE Year<>'Year';
DECLARE #var CHAR(20)
DECLARE #str VARCHAR(1000)
DECLARE myCursor CURSOR
FOR SELECT distinct [FILE_NAME] FROM #TEMP
--SET #str=''
OPEN myCursor
--'''+#var+''',
FETCH NEXT FROM myCursor INTO #var
WHILE ##FETCH_STATUS=0
BEGIN
SET #str=' INSERT INTO [dbo].[ABI_IND_STR_PLAN_DAILY] SELECT
* from [dbo].[ABI_IND_STR_PLAN_DAILY] WHERE FILE_NAME='+#var ---------------- Change GL Period Accordingly , for eg if it is JUN YTD then GL period '<=6' if only JUN MTD then GL Period = 6
FETCH NEXT FROM myCursor INTO #var
PRINT(#str)
EXEC(#str)
END
CLOSE myCursor
DEALLOCATE myCursor

Transact sql : must declare the scalar variable

I'm trying to iterate over some tables and clear all records.
My code is the following :
DECLARE #table varchar(100)
DECLARE db_cursor CURSOR FOR select name from sys.tables where name like '%cfe_%'
OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO #table
WHILE ##FETCH_STATUS = 0  
BEGIN  
print #table
delete from #table
       FETCH NEXT FROM db_cursor INTO #table  
END  
CLOSE db_cursor  
DEALLOCATE db_cursor
But I receive "Must declare the table variable "#table" at the line "delete..."
I can't see the error.
Thank you
You shoud use dynamic query,
DECLARE #table varchar(100)
,#v_str nvarchar(200)
DECLARE db_cursor CURSOR FOR select name from sys.tables where name like '%cfe_%'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #table
WHILE ##FETCH_STATUS = 0
BEGIN
print #table
set #v_str = 'delete from '+#table
exec(#v_str)
FETCH NEXT FROM db_cursor INTO #table
END
CLOSE db_cursor
DEALLOCATE db_cursor
You need dynamic delete statement... Try this :
DECLARE #cmd VARCHAR(4000)
DECLARE #table varchar(100)
DECLARE db_cursor CURSOR FOR select name from sys.tables where name like '%cfe_%'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #table
WHILE ##FETCH_STATUS = 0
BEGIN
SET #cmd = 'DELETE FROM '+#table
EXEC (#cmd)
FETCH NEXT FROM db_cursor INTO #table
END
CLOSE db_cursor
DEALLOCATE db_cursor
Even better would be to not use a cursor here. Looping in sql is a last resort. Also, your query is not going to do exactly what you think it will because you are using like and wanting to find an underscore. The underscore in a LIKE predicate requires it to be escaped with square brackets. As posted your query will return any table with cfe in the name not cfe_.
Once you are comfortable that the dynamic sql string is what you want you can uncomment it to execute it.
declare #SQL nvarchar(max) = ''
select #SQL = #SQL + 'delete from ' + name + ';'
from sys.tables
where name like '%cfe[_]%'
select #SQL
--exec sp_executesql #SQL
We can also use while loop for this process
DECLARE #Min Int,#max Int
IF Object_id('Tempdb..#DeleteList')IS NOT NULL
DROP TABLE #DeleteList
CREATE TABLE #DeleteList (Id Int Identity,Name varchar(100))
INSERT INTO #DeleteList(Name)
SELECT name FROM sys.tables WHERE CHARINDEX('cfe_',name)>0
SELECT #Min=Min(Id) FROm #DeleteList
SELECT #max=MAX(Id) FROm #DeleteList
While(#Min<=#max)
Begin
Declare #TableName Varchar(50),
#Sql Nvarchar(max)
SELECT #TableName=Name From #DeleteList Where id=#Min
SET #Sql='DELETE From '+#TableName
Exec (#Sql)
SET #Min=#Min+1
END
But if the deleting tables have foreign key refrences it will throw error so that first you need delete records from child and then go to Parent table
You will need to do something like;
EXEC sp_executesql #statement = N'DELETE FROM ' + #table
because currently you are trying to delete from a String variable, not the table named the same as the variable

How to use parameter variables in Cursor SQL

I am writing a Scalar function for my web application. I want to calculate the date difference between an employee's Join Date and Resign Date.
I have got most of my code working, but I just cannot figure out how to use parameter variables in cursor.
Let say I have this block of code
Declare myCursor Cursor for
Declare #join_date datetime
Declare #resign_date datetime
Declare #emp_stat nvarchar(50)
--What I have been trying to do. (Not working)
Select #join_date = Convert(datetime, join_date), #emp_stat = Convert(datetime, emp_stat) from t_emp_info where .....
OPEN product_cursor
WHILE ##FETCH_STATUS = 0
BEGIN
if (#emp_stat = 'P')
Begin
//DateDiff .....
End
FETCH NEXT FROM vendor_cursor
INTO #join_date , #emp_stat
End
Close myCursor
DEALLOCATE myCursor;
I can't get this working, but what I want is I want to store the values in the parameter so I can use it in the if condition statement. Not sure how to fix this. Help will be appreciated
Your cursor names are mixed up and your assignment is in the wrong place. Try:
Declare myCursor Cursor for
Select join_date, emp_stat, resign_date from t_emp_info where .....
Declare #join_date datetime
Declare #resign_date datetime
Declare #emp_stat nvarchar(50)
OPEN myCursor
FETCH NEXT FROM myCursor
INTO #join_date , #emp_stat , #resign_date
WHILE ##FETCH_STATUS = 0
BEGIN
//Your logic here
FETCH NEXT FROM myCursor
INTO #join_date , #emp_stat, #resign_date
End
Close myCursor
DEALLOCATE myCursor;
However you should avoid the cursor. What is wrong with:
SELECT DATEDIFF(day, MAX(join_date), case when emp_stat = 'P' then getdate() else MAX(resign_date) end)
from t_emp_info
GROUP BY employee_id
Or similar?

T-SQL cursor encoding

I have a table with column with cyrillic text. I want to iterate the table and proccess the rows one by one.
DECLARE #safeSize VARCHAR(50)
DECLARE #safeId INT
DECLARE db_cursor CURSOR FOR
select coalesce(s.id,0), coalesce(s.size,'-')
from old_nom_trezor s
order by s.id
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #safeId, #safeSize
WHILE ##FETCH_STATUS = 0
BEGIN
print #safeSize -- prints ???
print #safeId -- prints ???
--Insert statement with the vars. Also inserts ?
FETCH NEXT FROM db_cursor INTO #safeId, #safeSize
END
CLOSE db_cursor
DEALLOCATE db_cursor
The problem is that the cyrillic symbols are printed as ? and also if I insert them in other table the result is ?. Simple select in the Management studio displays the right symbols. How can I fetch the cyrillic symbols in cyrillic?
Cyrillic text consists of unicode characters, which can't be stored in a VARCHAR datatype.
Change this DECLARE #safeSize VARCHAR(50)
to this DECLARE #safeSize NVARCHAR(50)

Invalid cursor state

We have triggers on a table called OSPP to save specific data to a table for later use.
I get the following error in SAP when adding more than one line at a time to the table.
Invalid Cursor State
We have SQL Server 2005 SP3 (but I tried it on a clean 2005 install, on SP1 and SP2)
The one trigger :
CREATE TRIGGER [dbo].[tr_OSPP_Insert]
ON [dbo].[OSPP]
FOR INSERT
AS
BEGIN
Declare #ItemCode varchar(255)
Declare #CardCode varchar(255)
Declare #Price decimal(18,2)
Declare #ListNum bigint
Declare #ID bigint
Declare #Remote char(1)
DECLARE db_cursor CURSOR FOR
SELECT ItemCode, CardCode, Price, ListNum
FROM INSERTED
OPEN db_cursor
FETCH NEXT
FROM db_cursor INTO #ItemCode, #CardCode, #Price, #ListNum
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #Remote = isnull(U_Remote, 'N') FROM OITM WHERE ItemCode = #ItemCode
IF ltrim(rtrim(upper(#Remote))) = 'Y'
BEGIN
SELECT #ID = U_ID FROM [dbo].[#BDS_MAINTENANCE]
UPDATE [dbo].[#BDS_MAINTENANCE] set U_ID = U_ID + 1
INSERT INTO [dbo].[#BDS_REMOTESPECIALPRICELIST]
(
Code,
[Name],
U_ID,
U_ItemCode,
U_CardCode,
U_Price,
U_ListNum,
U_TransactionType,
U_Uploaded
) VALUES (
#ID,
'_' + cast(#ID as VARCHAR(50)),
#ID,
#ItemCode,
#CardCode,
#Price,
#ListNum,
1,
0
)
FETCH NEXT
FROM db_cursor INTO #ItemCode, #CardCode, #Price, #ListNum
END
CLOSE db_cursor
DEALLOCATE db_cursor
END
END
We also tried :
CREATE TRIGGER [dbo].[tr_OSPP_Insert]
ON [dbo].[OSPP]
FOR INSERT
AS
BEGIN
SELECT * INTO [#TEMPTABLE222] FROM INSERTED
END
But still get the same error.
Do you guys have any idea what is wrong?
Thanks in advance!
I count three Begins, and three Ends. But it's the second pair that represent the cursor loop - so I'd move your Close/Deallocate to be after the second End, rather than before. E.g:
FETCH NEXT
FROM db_cursor INTO #ItemCode, #CardCode, #Price, #ListNum
END
CLOSE db_cursor
DEALLOCATE db_cursor
END
Probably needs to be:
END
FETCH NEXT
FROM db_cursor INTO #ItemCode, #CardCode, #Price, #ListNum
END
CLOSE db_cursor
DEALLOCATE db_cursor
(I've also moved the fetch next one level out, since otherwise you only move the cursor forwards inside your IF condition)
And one style comment (can't resist). It's generally considered good practice to SET NOCOUNT ON within the body of a trigger, to avoid sending lots of extra n rows affected messages.

Resources