SQL Server skips RAISERROR - sql-server-2008-r2

Simple code. Very strange behaviour, triple checked this. #filePath and #path are NVARCHAR(260) and #exists is INT. dbo.WriteToFile writes a file to disk, in this case an empty file.
EXEC master..xp_fileexist #filePath, #exists OUTPUT
print #exists
IF #exists = 0
BEGIN
EXEC dbo.WriteToFile N'', #path, #filename
RAISERROR('A', 20, -1) WITH log
END
RAISERROR('B', 20, -1) WITH log
When I run this code for the first time and #exists is 0, it goes into the if block. File is created as expected. Confirmed that. But RAISERROR in the if block is not called. Instead only the RAISERROR outside the if block is called.
But if I replace the first RAISERROR ('A') with PRINT 'blabla' the print statement is called as expected.
If I replace #exists = 0 with 1=1 and keep the first RAISERROR ('A') as is, again everything behaves correctly and the first RAISERROR ('A') is called.
Can someone explain this?
Oh yeah, and why does
print 'bla'
raiserror('bla', 20, -1) with log
in a brand new query window get me this:
bla
Meldung 2745, Ebene 16, Status 2, Zeile 3
Der Prozess mit der ID 54 hat den Benutzerfehler 50000, Schweregrad 20, ausgelöst. Dieser Prozess wird von SQL Server beendet.
bla
Meldung 2745, Ebene 16, Status 2, Zeile 3
Der Prozess mit der ID 54 hat den Benutzerfehler 50000, Schweregrad 20, ausgelöst. Dieser Prozess wird von SQL Server beendet.
This is 2 times the same message. Maybe my SQL server is configured incorrectly?
I will post the WriteToFile procedure too if you are interested, maybe it helps, I have this procedure from the web, but it works perfectly, but maybe it produces the RAISERROR behaviour:
ALTER PROCEDURE dbo.WriteToFile
(
#String Varchar(max), --8000 in SQL Server 2000
#Path VARCHAR(255),
#Filename VARCHAR(100)
)
AS
BEGIN
DECLARE #objFileSystem int
,#objTextStream int,
#objErrorObject int,
#strErrorMessage Varchar(1000),
#Command varchar(1000),
#hr int,
#fileAndPath varchar(80)
select #strErrorMessage='opening the File System Object'
EXECUTE #hr = sp_OACreate 'Scripting.FileSystemObject' , #objFileSystem OUT
Select #FileAndPath=#path+'\'+#filename
if #HR=0 Select #objErrorObject=#objFileSystem , #strErrorMessage='Creating file "'+#FileAndPath+'"'
if #HR=0 execute #hr = sp_OAMethod #objFileSystem , 'CreateTextFile'
, #objTextStream OUT, #FileAndPath,2,True
if #HR=0 Select #objErrorObject=#objTextStream,
#strErrorMessage='writing to the file "'+#FileAndPath+'"'
if #HR=0 execute #hr = sp_OAMethod #objTextStream, 'Write', Null, #String
if #HR=0 Select #objErrorObject=#objTextStream, #strErrorMessage='closing the file "'+#FileAndPath+'"'
if #HR=0 execute #hr = sp_OAMethod #objTextStream, 'Close'
if #hr<>0
begin
Declare
#Source varchar(255),
#Description Varchar(255),
#Helpfile Varchar(255),
#HelpID int
EXECUTE sp_OAGetErrorInfo #objErrorObject,
#source output,#Description output,#Helpfile output,#HelpID output
Select #strErrorMessage='Error whilst '
+coalesce(#strErrorMessage,'doing something')
+', '+coalesce(#Description,'')
raiserror (#strErrorMessage,16,1)
end
EXECUTE sp_OADestroy #objTextStream
EXECUTE sp_OADestroy #objTextStream
END
edit: running SQL Server 2008 R2

I dont know if you really need a "20" error level, but please try with:
RAISERROR('A', 16, -1) WITH log

Related

Retrieve result from cursor of oracle storedprocedure in Perl Script

I am finding difficulty in fetching the records from stored procedure(oracle) by invoking it through perl script. SP takes 1 input and ouput parameter is cursor
--------Here is the perl script_-------------
my $dbh = DBI->connect("dbi:Oracle://**********",'**',***) or die "Couldn't connect to database: " . DBI->errstr;// successfully connected
my $cursorRecords;
my $categoryBind = 'tkuat';
my $sth= $dbh->prepare(q{
BEGIN
GetJobEnvironments(:category,:cursorTest);
END;
});
$sth->bind_param(":category", $categoryBind);
$sth->bind_param_inout(":cursorTest", \$cursorRecords,20000,{ ora_type => ORA_RSET});
$sth->execute or die "Can't execute SQL statement\n";
my #row=$cursorRecords->fetchrow_array();
print("row:#row\n");
print("cursorRecords:$cursorRecords\n");
print Dumper($sth);
script is executing but not printing the records from the database
---O/p:--------
row:
cursorRecords:DBI::st=HASH(0x1564318)
$VAR1 = bless( {}, 'DBI::st' );
------------------------------
SP in Database looks as below
create or replace PROCEDURE GetJobEnvironments
(
v_category IN CHAR DEFAULT NULL,
v_cursor OUT SYS_REFCURSOR
)
AS
BEGIN
IF ( v_category IS NULL ) THEN
BEGIN
OPEN v_cursor FOR
SELECT EnvVar ,
VALUE
FROM JobEnvironments ;
END;
ELSE
BEGIN
OPEN v_cursor FOR
SELECT EnvVar ,
VALUE
FROM JobEnvironments
WHERE Category = v_category ;
END;
END IF;
EXCEPTION
WHEN OTHERS THEN raise_application_error(-20002,SQLCODE||':'||SQLERRM);
END;
Table JobEnvironments also has a records
Can the reference in bind() $cursorRecords can hold records from a table?
Can someone please help with this?
----record from the table------
select * from JobEnvironments
Category,EnvVar,Value,last_update
-----------------------------------
tkuat','REUTFEED_SUBJ','RSF.REC',;\'2010-04-07 06:00:33.0'

CHARINDEX in SQL Server 2008 TSQL with inconsistent results

When I run the following code examples: I get different results (Shown below). Please explain why I get a match in the second example? I must be missing some understanding.
print ##version
-- First example behaves as expected
declare #strSearch nvarchar(10) = 'x (20) ';
declare #definition nvarchar(100) = 'x (200000000) ';
print charindex(#strSearch, #definition);
go
-- Second example does not behave as expected
declare #strSearch nvarchar(10) = 'xrchar (20) ';
declare #definition nvarchar(100) = 'xrchar (200000000) ';
print charindex(#strSearch, #definition);
Results below: (0 'not found' and 1 'found'):
Microsoft SQL Server 2008 (SP3) - 10.0.5538.0 (X64) Apr 3 2015
14:50:02 Copyright (c) 1988-2008 Microsoft Corporation Enterprise
Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1)
(VM)
0 1
The reason you get 1 in the second example is that you are setting a value to your #strSearch that is too long for the variable definition, so sql server trims it to fit the length of the variable (instead of raising a "string or binary data would be truncated" error).
You can see it if you alter the script a little bit:
First example:
declare #strSearch nvarchar(10) = 'x (20) ';
declare #definition nvarchar(100) = 'x (200000000) ';
SELECT #strSearch as '#strSearch',
#definition as '#definition',
charindex(#strSearch, #definition) as 'charindex';
results:
#strSearch #definition charindex
x (20) x (200000000) 0
Second example:
declare #strSearch nvarchar(10) = 'xrchar (20) ';
declare #definition nvarchar(100) = 'xrchar (200000000) ';
SELECT #strSearch as '#strSearch',
#definition as '#definition',
charindex(#strSearch, #definition) as 'charindex';
results:
#strSearch #definition charindex
xrchar (20 xrchar (200000000) 1
You can see a live demo on rextester (Turns out that in 2014 that behavior still continues).

TSQL procedure call to PLSQL procedure : ORA-06502: PL/SQL: numeric or value error

I have a T-SQL procedure calling an Oracle procedure passing in some parameters.
My oracle procedure works fine and returns the output parameters as expected.
However when calling the oracle procedure from the T-SQL procedure, I have the following error. I can't understand why am I getting this. Varchars are being used in both procedures.
(1 row(s) affected) OLE DB provider "OraOLEDB.Oracle" for linked
server "ORA_LINK_SERVER" returned message "ORA-06502: PL/SQL: numeric
or value error ORA-06512: at "DBNAME.GETSHELLACNOANDINSTRUCTIONNO",
line 7".
(1 row(s) affected)
(1 row(s) affected) Msg 7215, Level 17, State 1, Procedure
USP_TXN_PF_CLIENT_URL_NEW, Line 56 Could not execute statement on
remote server 'ORA_LINK_SERVER'.
This is my T-SQL procedure
USE [TVE]
GO
/****** Object: StoredProcedure [CompanyName].[USP_TXN_PF_CLIENT_URL] Script Date: 12/29/2016 11:14:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--To test +
/*
Declare #ReturnString varchar(255)
EXEC [CompanyName].[USP_TXN_PF_CLIENT_URL_NEW] 'CompanyName','50585609',#ReturnString = #ReturnString OUTPUT
select #ReturnString
*/
/*
ALTER TABLE [dbo].[PF_CLIENT_URLS]
ADD [STATUS] VARCHAR(1) NULL
GO
SELECT * FROM [dbo].[PF_CLIENT_URLS]
*/
ALTER PROCEDURE [CompanyName].[USP_TXN_PF_CLIENT_URL_NEW]
(
#IN_PMancoID VARCHAR(10),
#IN_PInvestorRef VARCHAR(12),
#ReturnString varchar(255) OUTPUT
)
AS
BEGIN
DECLARE #runStr VARCHAR(2000)
DECLARE #URL varchar(36)
DECLARE #MessageID AS VARCHAR(40), #RecipientID AS VARCHAR(40), #FileName VARCHAR(40),#ResponseFileName VARCHAR(40), #Message VARCHAR(500),
#Cell VARCHAR(35), #OUT_ShellAccountNumber VARCHAR(40), #OUT_InstructionNumber VARCHAR(40)
DECLARE #ParamKeys VARCHAR(max), #ParamValues VARCHAR(max), #Return_ID INT, #Current_User_ID INT,
#ErrorNumber INT, #ErrorSeverity INT, #ErrorState INT, #ErrorLine INT,
#ErrorMessage nVARCHAR(2048), #LogInfo_ID INT, #ProcedureName NVARCHAR(126),
#ProfileName VARCHAR(50), #Recipients VARCHAR(max), #Subject VARCHAR(100), #Body VARCHAR(max)
Set #ProcedureName = 'YYYY.USP_PF_CLIENT_URL_NEW'
Set #ParamKeys = ''
Set #ParamValues = ''
set #URL = newID()
Set #ParamKeys = 'IN_PMancoID' + '|' +
'IN_PInvestorRef'
Set #ParamValues = ISNULL(CONVERT(VARCHAR(max),#IN_PMancoID),'NULL') + '|' +
ISNULL(CONVERT(VARCHAR(max),#IN_PInvestorRef),'NULL')
exec [DYNAMIC].[ss_StoredProcLogInfo_Save] #ProcName = #ProcedureName,
#ParameterKeys = #ParamKeys,
#ParameterValues = #ParamValues,
#User_ID = #Current_User_ID,
#Return_ID = #Return_ID OUTPUT
exec ('CALL DBNAME.GETSHELLACNOANDINSTRUCTIONNO(?,?,?)', #IN_PInvestorRef, #OUT_ShellAccountNumber, #OUT_InstructionNumber) AT ORA_LINK_SERVER
INSERT INTO [dbo].[TableName]([UserID],[MancoID],[Reference],[DateCreated],[LoginAttempts],[STATUS],[ShellAccount],[InstructionNumber])
values(ISNULL(#URL, ''),'CompanyName',ISNULL(#IN_PInvestorRef, ''),getdate(),0,'I', ISNULL(#OUT_ShellAccountNumber,''),ISNULL(#OUT_InstructionNumber,''))
set #ReturnString = #URL
--Select #ReturnString as ReturnString
END
And this is my oracle procedure. The link server is fine.
CREATE OR REPLACE
PROCEDURE GETSHELLACNOANDINSTRUCTIONNO
( IN_PInvestorRef IN VARCHAR2(12)
, OUT_ShellAccountNumber OUT VARCHAR2(40)
, OUT_InstructionNumber OUT VARCHAR2(40)
) AS
BEGIN
Select SHELL_ACCOUNT, INSTRUCTIONNUMBER into OUT_ShellAccountNumber, OUT_InstructionNumber
from pf
where client_id = IN_PInvestorRef;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END GETSHELLACNOANDINSTRUCTIONNO;

how to use select case statement with sql transaction

i have one crm application. i found query in my db implementation while staff user post reply of inquiry i have to insert new inquiry ans to one table and modify another table data same time. i applied logic of as well as i represent my stored proc. but error occured in this proc.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[InquiryPostReply]
(
#Inquiry_id VARCHAR(50),
#Priority_type VARCHAR(25),
#Status_name VARCHAR(50),
#Inquiry_Content VARCHAR(1024),
#NewId VARCHAR(50) OUT
)
AS
BEGIN
SET NOCOUNT ON;
declare #var1 int
declare #var2 int
declare #uniqueRef char(14)
set #uniqueRef = dbo.UniqueRefNum(rand(), rand(), rand(), rand())
set #var1= (SELECT [Id] FROM [OmStocks].[dbo].[tbl_Status_master] WHERE (Status_name=#Status_name))
set #var2= (SELECT [Id] FROM [OmStocks].[dbo].[tbl_Priority_master] WHERE (Priority_name=#Priority_type))
SELECT
CASE #Status_name
WHEN 'Open' THEN
BEGIN TRAN;
BEGIN TRY
INSERT INTO [OmStocks].[dbo].[tbl_Inquiry_master]
([Id],[Inquiry_id],[Priority_id],[Status_id],[Inquiry_Content],[TimeStamp])
VALUES
(#uniqueRef,#Inquiry_id,#var2,#var1,#Inquiry_Content,CONVERT(DATETIME,GETDATE(), 101))
UPDATE [OmStocks].[dbo].[tbl_Inquiry_History]
SET [Priority_id] = #var2,[Status_id] = #var1,[IsDisplay] = 1,[IsReplied] = 1,[TimeStamp] = CONVERT(DATETIME,GETDATE(), 101)
WHERE (Inquiry_id=#Inquiry_id)
COMMIT TRAN;
END TRY;
WHEN 'Close' THEN
BEGIN TRAN;
BEGIN TRY
INSERT INTO [OmStocks].[dbo].[tbl_Inquiry_master]
([Id],[Inquiry_id],[Priority_id],[Status_id],[Inquiry_Content],[TimeStamp])
VALUES
(#uniqueRef,#Inquiry_id,#var2,#var1,#Inquiry_Content,CONVERT(DATETIME,GETDATE(), 101))
UPDATE [OmStocks].[dbo].[tbl_Inquiry_History]
SET [Priority_id] = #var2,[Status_id] = #var1,[IsDisplay] = 0,[IsReplied] = 1,[TimeStamp] = CONVERT(DATETIME,GETDATE(), 101),[Activity_expire_time] = CONVERT(DATETIME,GETDATE(), 101)
WHERE (Inquiry_id=#Inquiry_id)
COMMIT TRAN;
END TRY;
END
SET #NewId = #uniqueRef
END
error occured like:
Msg 156, Level 15, State 1, Procedure InquiryPostReply, Line 21
Incorrect syntax near the keyword 'BEGIN'.
Msg 102, Level 15, State 1, Procedure InquiryPostReply, Line 31
Incorrect syntax near ';'.
Msg 102, Level 15, State 1, Procedure InquiryPostReply, Line 43
Incorrect syntax near ';'.
Msg 102, Level 15, State 1, Procedure InquiryPostReply, Line 46
Incorrect syntax near 'END'.
please help me...
You can't use CASE for this. CASE is an expression that returns a single result, not a statement that can be used for control-of-flow. I do understand that CASE is used that way in some other languages, but it's just not possible in T-SQL.
IF #Status_name = 'Open' THEN
BEGIN
-- do stuff
END
IF #Status_name = 'Close' THEN
BEGIN
-- do other stuff
END

DB2 Create Table X when X is a variable?

In Oracle, we do this:
def TNAME=&1
create table &TNAME (foo varchar(10));
How to do the equivalent for DB2? The constraints are:
1. The create table statement is generated when TNAME is unknown
2. The create table statement is in a file which cannot be modified
3. Cannot create a temporary file with TNAME substituted by awk
4. Essentially we want to pass in the table name at run time as an argument
Possible?
The EXECUTE IMMEDIATE statement can be used in just about any block of SQL that is surrounded by a BEGIN and END, such as a stored procedure or anonymous compound statement.
CREATE PROCEDURE create_table_from_file( IN fileDir VARCHAR( 1024 ),
IN fileName VARCHAR( 128 ),
IN tabSchema VARCHAR( 128 ),
IN tabName VARCHAR( 128 )
)
BEGIN
DECLARE fh UTL_FILE.FILE_TYPE;
DECLARE sqlStmt VARCHAR( 32672 );
DECLARE currentLine VARCHAR( 32672 );
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';
DECLARE CONTINUE HANDLER FOR SQLSTATE 'ORANF' SET SQLSTATE1 = SQLSTATE;
SET sqlStmt = 'CREATE TABLE '
|| CASE WHEN ( NULLIF( tabSchema, '' ) IS NOT NULL )
THEN RTRIM( tabSchema ) || '.'
ELSE '' END || tabName;
CALL UTL_DIR.CREATE_OR_REPLACE_DIRECTORY( 'createTablePath', fileDir );
SET fh = UTL_FILE.FOPEN( 'createTablePath', fileName, 'r' );
loop1: LOOP
CALL UTL_FILE.GET_LINE( fh, currentLine );
IF SQLSTATE1 = 'ORANF' THEN -- NO DATA FOUND
LEAVE loop1;
END IF;
SET sqlStmt = sqlStmt || ' ' || currentLine ;
END LOOP;
EXECUTE IMMEDIATE sqlStmt;
END
#
I created a file abc containing:
create table TNAME (foo varchar(10))
Then I did, on a Unix command-line:
sed s/TNAME/xyz/g abc | db2
which created a table called xyz in DB2 as I wanted. Thanks.