How to Deal with SET ANSI_NULLS ON or OFF? - sql

I want to call this procedure that sends one value that can be NULL or any int value.
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId =#SubDomainId
I simply want to use this single query rather than what i m doing right now in below given code.
I searched for this how could i do this then i got this Link.
According to this I have to set ANSI_NULLS OFF
I am not able to set this inside this procedure before executing my sql query and then reset it again after doing this.
ALTER PROCEDURE [Tags].[spOnlineTest_SubDomainSelect]
#SubDomainId INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF #SubDomainId IS NULL
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId IS NULL
ELSE
SELECT DomainName, DomainCode FROM Tags.tblDomain WHERE SubDomainId =#SubDomainId
END
What will be the better practice to do deal with ANSI_NULLS or Using If Else

SET ANSI_NULLS is ony defined at stored proc create time and cannot be set at run time.
From CREATE PROC
Using SET Options
The Database Engine saves the settings
of both SET QUOTED_IDENTIFIER and SET
ANSI_NULLS when a Transact-SQL stored
procedure is created or modified.
These original settings are used when
the stored procedure is executed.
Therefore, any client session settings
for SET QUOTED_IDENTIFIER and SET
ANSI_NULLS are ignored when the stored
procedure is running. Other SET
options, such as SET ARITHABORT, SET
ANSI_WARNINGS, or SET ANSI_PADDINGS
are not saved when a stored procedure
is created or modified. If the logic
of the stored procedure depends on a
particular setting, include a SET
statement at the start of the
procedure to guarantee the appropriate
setting. When a SET statement is
executed from a stored procedure, the
setting remains in effect only until
the stored procedure has finished
running. The setting is then restored
to the value the stored procedure had
when it was called. This enables
individual clients to set the options
they want without affecting the logic
of the stored procedure.
The same applies to SET QUOTED_IDENTIFIER
In this case, use IF ELSE because SET ANSI_NULLS will be ON in the future.
Or Peter Lang's suggestion.
To be honest, expecting SubDomainId = #SubDomainId to work when #SubDomainId is NULL is not really correct usage of NULL...

Can't you use a single query?
SELECT DomainName, DomainCode
FROM Tags.tblDomain
WHERE ( #SubDomainId IS NULL AND SubDomainId IS NULL )
OR ( SubDomainId = #SubDomainId )

FYI, I'm pretty sure ...
ANSI_NULLS OFF
Applies to the procedure when you create/edit it, it's like a setting of the procedure.
So either the procedure has it ON or OFF. Your example was a query not a procedure so I'm a little confused.
But if you have SQL 2005/2008 for example if you "edit" procedure it opens up your procedure in a new tab you'll see the ANSI_NULLS OFF near the top.
You can edit it there and set it ON or OFF and update it to change ...

Related

Update stored procedure using C#?

I have 10 database servers and most procedures are the same.
So I plan to make procedure distribute program.
For convenient application, I want to use "the procedure modify code made by tool" itself.
For example, when I click modify button of the procedure on SSMS the code is like below.
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[HongTestProcedure] Script Date: 2020-08-28 오전 11:09:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: hong
-- Create date: 2020-03-07
-- =============================================
ALTER PROCEDURE [dbo].[HongTestProcedure]
-- Add the parameters for the stored procedure here
#ID varchar(10)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT *
FROM table
END
And then, if I want to modify the parameter of the procedure.
Maybe the code is like below:
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[HongTestProcedure] Script Date: 2020-08-28 오전 11:09:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: hong
-- Create date: 2020-03-07
-- =============================================
ALTER PROCEDURE [dbo].[HongTestProcedure]
-- Add the parameters for the stored procedure here
#ID varchar(10)
#ID2 varchar(10) -- it is added.
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT *
FROM table
END
I consider that program has a textbox and button.
and I want to insert all above code.
maybe it looks like it:
So, I try the code like below:
public bool UpdateProcedure(string dbip, string query)
{
DataSet ds = new DataSet();
SqlConnection sqlConn = new SqlConnection("server = " + dbip + dbInfo);
sqlConn.Open();
SqlCommand sqlComm = new SqlCommand(query, sqlConn);
sqlComm.ExecuteNonQuery();
return true;
}
If it run successfully, I will run query on 10 database servers.
But it return error message. even it can be run in SSMS.
incorrect syntax near 'GO'
CREATE/ALTER PROCEDURE must be the first statement in a query batch
Can I solve it?
Yes. Since you can construct it as an Dynamic SQL in C# and Open an SQL Connection and pass the Dynamic SQL to EXEC sp_executesql #DynamicSQL. This will create the required SP in the required Database.

Store a generated SQL String into a table via Stored Procedure

I have an application where a user fills out a form which in turn generates a pretty lengthy Query. Well as part of a usage statistics program, I track and log everything our users do in one spot in the database. I have a stored procedure that inserts the appropriate values into this database, however the issue I'm running into is inserting the actual Query that took place.
Stored Procedure
USE [Worktool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Insert_Usage_Statistics]
-- Add the parameters for the stored procedure here
#Query_VC AS VARCHAR(MAX) = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO Usage_Statistics_T
(
Query_VC
)
VALUES
(
#Query_VC
)
END
Example of it being called
exec Worktool.dbo.Insert_Usage_Statistics
#Query_VC = 'SELECT col1 FROM tbl1 INNER JOIN tbl2 ON tbl1.id = tbl2.id WHERE tbl1.id IN ('1','2')'
The error I'm receiving is around the IN ('1','2') syntax.

How to execute a stored procedure after it is created?

I'm trying to execute a stored procedure directly after its creation however it is not getting called. It looks like the stored procedure is not yet created during the execution call.
Here is how the script looks like:
CREATE PROCEDURE sp_Transfer_RegionData
AS
BEGIN
INSERT INTO Region (regionName)
SELECT column1
FROM openquery(ITDB, 'select * from db.table1')
END
EXEC sp_Transfer_RegionData
The script runs fine however the needed table is not populated. After replacing the execution part with:
IF OBJECT_ID('sp_Transfer_RegionData') IS NOT NULL
begin
exec [dbo].[sp_Transfer_RegionData]
print 'tada'
end
I could see that the stored procedure does not exist when it has to be executed. Couldn't find a solution for this in the internet...
So how to make the SQL script run sync so that the stored procedure would already exist during the execution part?
You need a GO after you created the SP otherwise you have created a recursive SP that calls itself "indefinitely" which is 32 times in SQL Server.
Maximum stored procedure, function, trigger, or view nesting level
exceeded (limit 32).
Try this:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE sp_Transfer_RegionData
AS
BEGIN
INSERT INTO Region (regionName)
SELECT column1
FROM openquery(ITDB, 'select * from db.table1')
END
GO
EXEC sp_Transfer_RegionData

Cannot set IMPLICIT_TRANSACTIONS to OFF for stored procedure?

I have a Stored Procedure in which I'm NOT using any explicit Transaction related code (i.e. begin/rollback/commit transaction), and yet ##Trancount is set to 2 (I'm monitoring this by writing this value into a Table's row entry during the Stored Procedure). This obviously means thats IMPLICIT_TRANSACTIONS is set to ON somewhere.
I'm adding the following lines to the start of my Stored Procedure ....
SET IMPLICIT_TRANSACTIONS OFF
GO
.... So that it becomes this:
USE [RentTrackingSystem]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET IMPLICIT_TRANSACTIONS OFF
GO
ALTER PROCEDURE [RTS].[GenerateAnnualPenalty]
-- Add the parameters for the stored procedure here
#dueDate Date = NULL ,
#fiscalYear numeric(4),
#createdBy Varchar(50),
#referenceForm Varchar(50),
#referenceFormNo Varchar(50),
#PENALTY_NO int ,
#PenaltyCutOffDate date = NULL
AS
-- Rest of the body here ..
However when I execute the query (to Alter the Stored Procedure), close that window and then again open the same Stored Procedure's code, that addition goes away, and the Stored Procedure again becomes:
USE [RentTrackingSystem]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [RTS].[GenerateAnnualPenalty]
-- Add the parameters for the stored procedure here
#dueDate Date = NULL ,
#fiscalYear numeric(4),
#createdBy Varchar(50),
#referenceForm Varchar(50),
#referenceFormNo Varchar(50),
#PENALTY_NO int ,
#PenaltyCutOffDate date = NULL
AS
-- Rest of the body here ..
So what's going on here ?
You can't get SET IMPLICIT_TRANSACTIONS OFF before the body of the stored procedure because this is not a value that is captured when a stored procedure is created. When you set the implicit_transactions to off all you're doing is setting the the value for your connection so when you run your alter statement you'll be running it under the context of having implicit_transactions turned off, but there is no relation to that setting and what is captured for the stored procedure definition.
To put it another way there are many settings that are affecting your queries at any given time, but SQL Server only captures ANSI_NULLS and QUOTED_IDENTIFIER settings when creating a stored procedure.
Per MSDN:
When a stored procedure is created, the SET QUOTED_IDENTIFIER and SET ANSI_NULLS settings are captured and used for subsequent invocations of that stored procedure.
If you want the content of the sproc to be affected by the SET IMPLICIT_TRANSACTIONS OFF setting simply set it as the first thing after the Create Proc Name (variables Datatypes) As... sproc declaration.
Note that this is not going to clear out existing transactions. If you have transactions outside of the stored procedure they will still exist, this setting is simply going to prevent any new implied transactions from being created.

Failed to call a stored procedure within another stored procedure

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[SD_Sproc_Insurance_Insert]
-- Add the parameters for the stored procedure here
(
#HCSInsuranceID bigint,
#HCSInsuranceCode varchar(10),
#HCSInsuranceName varchar(100),
#IsPPS bit,
#IsActive bit
)
AS
BEGIN TRAN InsuranceInsert
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
INSERT INTO SD_Sproc_ToGRS_Insurance(HCSInsuranceID ,HCSInsuranceCode, HCSInsuranceName, IsPPS ,IsActive)
VALUES (#HCSInsuranceID ,#HCSInsuranceCode, #HCSInsuranceName, #IsPPS, #IsActive);
COMMIT TRAN InsuranceInsert
The SD_Sproc_ToGRS_Insurance is the stored that I'll call.. I'm having a problem to call this one. Anyone suggest? That I'm doing the right path to call a stored procedure?
The above is SQL Server syntax. Use the exec command like so to call a stored procedure.
exec storedProcName #param1Name, #param2Name