Linkserver update not working in Transaction - sql

I am trying to do operation on my linked server
created one linked server , everything is ok
just observed one thing which I am not able to understand
if I run
update SERVER.testdb.[AAA].MyTable
set MyName= 'abc#pqr.com'
where ID=999
This works fine ,but
when i execute same code in following way
BEGIN TRY
BEGIN TRANSACTION TRF
update SERVER.testdb.[AAA].MyTable
set MyName= 'abc#pqr.com'
where ID=999
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION TRF
END CATCH
It shows The parameter is incorrect
Can anyone tell me why this is hapeening and what is solution ?

Related

Tracking process of unknown origin, on SQL Server

I need some out-of-the-box thinking on this issue. It's weird.
I have a SQL Server environment (production) where I get a sporadic error executing a procedure.
dbo.proc_1_$sp
...
begin try
BEGIN
SELECT #errmsg = 'failed to execute proc2_$sp'
EXEC proc2_$sp;
END;
...
catch
... etc
EXEC proc2_$sp fails.
It returns error
failed to execute proc2_$sp
to a process log table.
The problem is... I don't execute dbo.proc_1_$sp.
I want to find out what executes it. It could be a test environment pointing to production, it could be a test script someone left running.
I want to know the hostname, the login name, or whatever info I can catch on this process.
I can't leave SQL Server Profiler trace on. I tried, but it's a prod environment and I can't let the trace running for hours.
The only way I can think of is to update the error message with more info, as below.
The problem is, since I don't know the login name, I can't ensure the user will have access to sys.sysprocesses and I might get a crash instead.
Any other suggestions on how I can grab process information without worrying about permission issues?
dbo.proc_1_$sp
...
begin try
BEGIN
SELECT #errmsg = 'failed to execute proc2_$sp'
select #errmsg = #errmsg + ' login_time:'+convert(nvarchar, login_time, 9)+' hostname:'+ltrim(rtrim(hostname)) + ' program_name:'+ltrim(rtrim(program_name))+' loginame:'+loginame
FROM sys.sysprocesses WHERE spid = ##SPID
EXEC proc2_$sp;
END;
...
catch
... etc

how to handle SQL failer from asterisk dial plan

Im using
Asterisk certified/16.8-cert2
MSSQL Express 2014
unixODBC 2.3.1
freetds v1.1.20
Lua 5.1.4
CentOS7
I doing update statement in SQL with func_odbc.so. The update statement is working fine with no issue. but I wanna away to be able to catch an error if it happens, like a disconnect or network interruption.
Here is my update statement
UPDATE Customers SET AccountBalance = AccountBalance - ${VAL1} WHERE cif = ${ARG1}
My dialPlan function call ( in extention.lua)
local statues = channel.ODBC_ErrorTest(1499):set(10)
One of the thing that I though I can make it work, is by adding TRY and CATCH blook in the SQL statement itself like below, so if there is an error it will return the error number
BEGIN TRY
UPDATE Customers SET AccountBalance = AccountBalance - a WHERE cif = 17399
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber
END CATCH
But when I try to execute this it does not return me an error number when there is a failer, just return an empty string.
So my question is simple, how to handle SQL failer from the dial plan?
For update it should return -1 in case of writesql error.
However you should understand, asterisk is PBX, not something suitable for complex sql check.
Possible workarounds
1) create other table with command, create external script which check it for new "actions" and send back results/error. Check in asterisk after 0.5sec, 1sec etc.
2) create simple rest API and use func_CURL.

Stop a stored procedure from further execution once the condition is violated?

I have a following stored procedure and i want to abort it once the number of rows in fact table are not similar to the historical data. So i'm trying to do something like, till now it only sends the email to the users that the data is not same but i want to add an another feature, i.e to abort/stop the SP if the rows difference is more than 5%. But it's not working properly. Can anyone explain where i'm making the mistake? Following is the chunk of stored procedure where i'm making modifications:
SET XACT_ABORT ON;
Begin Try
Begin Transaction;
if (#delta_ok = 0)
set #email_body = #email_body+char(13)+char(10)+'ETL process has been stopped.'
Return
else
set #email_body = #email_body+char(13)+char(10)+'ETL process is copying the data .'
Commit Transaction;
Begin Catch
Rollback Transaction
End Catch
End Try
So my question is that if put "RETURN" inside the "if" statement would it stop the SP? Once the condition is violated? And pass to "ELSE" if the condition isn't fulfilled?
Your syntax is all over the place here. Using some formatting to add clarity will help considerably. Also you have an anti-pattern in your code I call Try/Squelch. You catch an error but then you swallow it and don't tell anybody it happened. When exceptions happen you need to handle them. That means you need to tell the calling program something went wrong, not just silently ingest the details so nobody knows it happened or how to fix it.
Begin Try
Begin Transaction;
if (#delta_ok = 0)
begin
set #email_body = #email_body + char(13) + char(10) + 'ETL process has been stopped.'
Return
end
else
begin
set #email_body = #email_body + char(13) + char(10) + 'ETL process is copying the data .'
Commit Transaction;
end
End Try
Begin Catch
Rollback Transaction
--you really need something here to log/audit and probably tell the calling program something failed.
End Catch

Execute update clause even with errors

I'm doing some script testing and I want to make sure that if the Update Clause I'm testing in this Try Catch :
BEGIN TRY
BEGIN TRAN
UPDATE NAME
SET NAME.ADDBY =
(CASE WHEN NAME.ADDBY = 'CONVERSION' THEN 'CONVERTED'
WHEN NAME.ADDBY = 'CJDOG'THEN 'CJDAREME'
WHEN NAME.ADDBY = 'npalerm' THEN 'REALLYLONGDETAILEDTEXT'
ELSE NAME
END)
COMMIT TRAN
END TRY
BEGIN CATCH
IF ##TRANCOUNT >0
PRINT ERROR_MESSAGE()
ROLLBACK TRAN
END CATCH
PRINT ##TRANCOUNT
fails, that other rows are updated and only the ones that didn't error go through.
Currenty because it is in the TRY CATCH there is a ROLLBACK that makes sure nothing goes through.
But when I try to run just the UPDATE part the errors terminates the whole script, instead of updating those that do not cause an error, in this case npalerm is too long in the case.
Any Ideas?
I know its a long desc I could've just included the Update but for detailed purpose I included it in the Catch.
In order to update the rows individually and catch the errors on each row rather than catching errors on the entire table/view update, you would need to wrap the whole thing in a cursor.
Be aware that cursors are more resource intensive and slower than set-based commands.

A simple transaction doesn't work on SQL Server 2005

I am doing this in SQL Server 2005. I have a table, there is only one column of type int, o you cannot insert char in it.
DECLARE #intErrorCode INT
BEGIN TRAN
Update TestTable set A='a' where A=3 --UPDATE TO CHAR, FAIL
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO PROBLEM
COMMIT TRAN
PROBLEM:
IF (#intErrorCode <> 0) BEGIN
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
END
I am expecting to see 'Unexpected error occurred!' as result.
But what I actually see is:
Conversion failed when converting the varchar value 'a' to data type int.
It seems that my SQL Server doesn't take my code as a transaction at all... It hit the fail line and quit running right after that.
What am I doing wrong here?
First use Try catch blocks instead.
However, no sql error trapping will work for all types of errors.
Read about error handling using the try catch block in Books online and you will see a discussion of what types of errors are not trapped.
Also it is better to return the actual error than a general message usually. It is much easier to track down teh error issue when you know the real error.