I have stored procedure, i want to send it an array of values. When i send more than one i'm getting an error
Error converting data type varchar to numeric.
Here is the code.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_getTransfer] #TRANSFER_ID int = null, #COMPANY VARCHAR(5),#FORMTYPE VARCHAR(30), #TRANSFER_IDS VARCHAR(500) = NULL, #SEAL_DATE datetime = NULL AS
-- Declare variables
DECLARE #rc Int
IF #SEAL_DATE IS NULL
BEGIN
SELECT
COMPANY,
FORMTYPE,
COMPANY_NAME,
COMPANY_ADDRESS1,
COMPANY_ADDRESS2,
IMID,[DESCRIPTION],AMOUNT,AMOUNT_TRANSFER,
CONSIDERATION,
TRANSFER_ID,
[DATE],
CURR,
CMF_NAME_1,
CMF_NAME_2,
CMF_ADDR_1,
CMF_ADDR_2,
CMF_ADDR_3,
CMF_ADDR_4,
CMF_POSTAL_CODE,
Cons_Curr = CASE
WHEN LTRIM(RTRIM(Cons_Curr)) <> '' THEN Cons_Curr
ELSE CURR
END,
-- Cons_Curr,
TRANSFERYEAR,
TRANSFERMONTH,
TRANSFERDAY,
dbo.CurrencyToWords(CURR) AS CURR_WORDS,
---dbo.CurrencyToWords(Cons_Curr) AS CONNS_CURR_WORDS
CONS_CURR_WORDS = CASE
WHEN LTRIM(RTRIM(CONS_CURR)) <> '' THEN dbo.CurrencyToWords(CONS_CURR)
ELSE dbo.CurrencyToWords(CURR)
END
FROM
VW_TRANSFERS
WHERE
TRANSFER_ID= #TRANSFER_ID
AND
FORMTYPE= #FORMTYPE
AND
COMPANY = #COMPANY
OR
TRANSFER_ID IN (#TRANSFER_IDS)
END
ELSE
SELECT
COMPANY,
FORMTYPE,
COMPANY_NAME,
COMPANY_ADDRESS1,
COMPANY_ADDRESS2,
IMID,[DESCRIPTION],AMOUNT,AMOUNT_TRANSFER,
CONSIDERATION,
TRANSFER_ID,
[DATE],
CURR,
CMF_NAME_1,
CMF_NAME_2,
CMF_ADDR_1,
CMF_ADDR_2,
CMF_ADDR_3,
CMF_ADDR_4,
CMF_POSTAL_CODE,
--Cons_Curr,
Cons_Curr = CASE
WHEN LTRIM(RTRIM(Cons_Curr)) <> '' THEN Cons_Curr
ELSE CURR
END,
TRANSFERYEAR,
TRANSFERMONTH,
TRANSFERDAY,
dbo.CurrencyToWords(CURR) AS CURR_WORDS,
---dbo.CurrencyToWords(Cons_Curr) AS CONNS_CURR_WORDS
CONS_CURR_WORDS = CASE
WHEN LTRIM(RTRIM(CONS_CURR)) <> '' THEN dbo.CurrencyToWords(CONS_CURR)
ELSE dbo.CurrencyToWords(CURR)
END
FROM
VW_TRANSFERS
WHERE
FORMTYPE= #FORMTYPE
AND
COMPANY = #COMPANY
AND
DATE = #SEAL_DATE
OR
TRANSFER_ID IN (#TRANSFER_IDS)
EXEC sp_getTransfer NULL, fgb, transfer, '124,444,4555,8865,24,55,69', NULL
the following code cannot work:
TRANSFER_ID IN (#TRANSFER_IDS)
Several working alternatives described here:
Arrays and Lists in SQL Server
you would have to set this up as a dynamic stored procedure or loop through the ids in code and call the stored proc each time. Do you know how to set up a dynamic procedure?
EXAMPLE
ALTER Procedure [dbo].[sp_NAME]
(#id as varchar(max)
)
as
Declare #query1 as nvarchar(max)
If #Param is null
set #Param = ''
Set #query1 = '
select whatever
from table
where id in('+#id+')'
EXECUTE sp_executesql #query1
Related
Here's what I have so far but I can't get it to run properly. I keep getting an error that the syntax is incorrect ON FROM where it reads FROM TBL_AIRPORT AIR. But I can't figure out what is supposed to be there, or what to change so I can't run it. Any help would be appreciated.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE SP_GETAIRPORTS
#GEOLOCATION GEOGRAPHY = NULL,
#ICAOCODE VARCHAR(10) = NULL,
#IATACODE VARCHAR(4) = NULL,
#COUNTRY_FK INT = NULL,
#STRNAME VARCHAR(MAX) = NULL,
#STRCITY VARCHAR(MAX) = NULL,
#INT_ELEVATION INT = NULL
AS
BEGIN TRANSACTION
BEGIN TRY
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
SELECT
GEOLOCATION.LAT, GEOLOCATION.LONG, ICAOCODE, IATACODE,
STRNAME, STRCITY, COUNTRY.COUNTRYNAME, INT_ELEVATION
FROM
TBL_AIPORT AIR
FROM
TBL_AIRPORT AIR
JOIN
TBL_COUNTRY C ON C.COUNTRY_ID = AIR.COUNTRY_FK
WHERE
GEOLOCATION.LAT <> 0 OR GEOLOCATION.LONG <> 0
END TRY
BEGIN CATCH
-- .....
END CATCH
Rewrite your select clause, because you used 'TBL_AIRPORT' table twice with same key word 'FROM' and also properly write begin and commit transactions syntax.
SELECT
GEOLOCATION.LAT, GEOLOCATION.LONG, ICAOCODE, IATACODE, STRNAME,
STRCITY, COUNTRY.COUNTRYNAME, INT_ELEVATION
FROM
TBL_AIRPORT AIR
JOIN
TBL_COUNTRY C ON C.COUNTRY_ID = AIR.COUNTRY_FK
WHERE
GEOLOCATION.LAT <> 0 OR GEOLOCATION.LONG <> 0
I'm developing a SQL Server 2012 stored procedure.
I need to return a list of nvarchar(20) values, and I don't know how can I do it. I have tried this:
Using a Table-Valued Parameters but it must be READONLY.
Doing a select to return that list. But stored procedures only
returns INT values.
Any idea?
UPDATE:
This is what I have done:
CREATE PROCEDURE [dbo].[GetAggregationChildren]
#parentCode nvarchar(20),
#codeLevel tinyint output,
#returnValue int output
AS
declare #childsLevelCount tinyint
, #invalidChildCodesCount int;
set nocount on;
-- ======== VALIDATION ==========
if NULLIF(#parentCode, '') IS NULL
begin
set #returnValue = -19;
return NULL; -- Parameter null or empty.
end
-- Check if parent exists in AGGREGATIONS table.
if not exists (Select top 1 CODE from AGGREGATIONS where CODE = #parentCode)
begin
set #returnValue = -11;
return NULL;
end
set #childsLevelCount = (select count(c.CODE_LEVEL) from CODES c where c.CODE in (Select CODE from AGGREGATION_CHILDS where PARENT_CODE = #parentCode) group by c.CODE_LEVEL);
-- If this aggregation has children codes with different values, it is an error.
if (#childsLevelCount > 1)
begin
set #returnValue = -201;
return NULL;
end
-- =========== CODE =============
set #returnValue = 0;
set #codeLevel = (select c.CODE_LEVEL from CODES c where c.CODE in (Select CODE from AGGREGATION_CHILDS where PARENT_CODE = #parentCode) group by c.CODE_LEVEL);
select CODE from AGGREGATION_CHILDS where PARENT_CODE = #parentCode;
But, I have no idea about how to return the result of this select:
select CODE from AGGREGATION_CHILDS where PARENT_CODE = #parentCode;
This stored procedure returns this on SQL Server Management Studio:
It is also returning a 0. I thought that the stored procedure is going to return the select result only.
I need the result in a parameter because I going to use in a SQLCommand like this one:
SqlParameter childsParam = new SqlParameter();
childsParam.ParameterName = "#childs";
childsParam.SqlDbType = System.Data.SqlDbType.Structured;
childsParam.Direction = System.Data.ParameterDirection.Input;
childsParam.Value = tvp;
parameters = new List<SqlParameter>();
parameters.Add(childsParam);
SqlConnection connection =
_context.Database.Connection as SqlConnection;
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = storedProcedureName;
cmd.CommandType = CommandType.StoredProcedure;
if (parameters != null)
cmd.Parameters.AddRange(parameters.ToArray());
cmd.Connection = connection;
cmd.ExecuteNonQuery();
connection.Close();
Stored procedure returns only Integer?
No this is not 100% true. If you are using RETURN to return the values from your stored procedure then your statement is true else it is false.
If you want to return string from your stored procedure then you can use SELECT like this:
CREATE PROCEDURE myProc
AS
BEGIN
SELECT 'test'
END
And to return multiple values you can use it like
CREATE PROCEDURE myProc
#Value1 varchar(20) OUTPUT,
#Value2 varchar(20) OUTPUT
AS
SELECT #Value1 = 'test1', #Value2 = 'test2'
and call it like
DECLARE #Value1 varchar(20), #Value2 varchar(20)
exec myProc #Value1 OUTPUT, #Value2 OUTPUT
SELECT #Value1, #Value1
Stored procedures return the type of the field in the SELECT statement. You can use CAST and CONVERT to change the types. For example:
SELECT CAST(field AS NVARCHAR(20))
With table value parameters you can set the field type on creation:
CREATE TYPE JobSpecifications AS TABLE
(JobName VARCHAR(50), AvailableDate Date );
you can use a temporary table to recuperate your list from the stored procedure, like the example below :
create proc Test
AS BEGIN
SELECT CAST('jkj' AS NVARCHAR(20)) value
END
DECLARE #tmp TABLE(value nvarchar(20))
INSERT INTO #tmp EXEC GhaziTest
SELECT * from #tmp
I have some trouble creating a dynamic Where clause.
I would like to pass in a parameter to a function, and then use that parameter to retrieve values from the database and use that in my Where clause, and then return a resulting value.
I've tried numerous options, but my best try so far is:
CREATE FUNCTION dbo.GetID (#TaskID varchar(10))
RETURNS Int
AS
BEGIN
DECLARE #TaskType varchar(10)
DECLARE #TaskSubType TinyInt
DECLARE #ID Int
DECLARE #SQL varchar(400)
SELECT #TaskType = TaskType, #TaskSubType = TaskSubType
FROM Tasks
WHERE TaskID = #TaskID
SET #SQL = 'SELECT #ID = ID
FROM ZCircuitFaults
WHERE TaskType = #TaskType AND ' +
CASE WHEN ISNULL(#TaskSubType, '') <> ''
THEN '(TaskSubType Is Null OR TaskSubType = CAST(#TaskSubType AS Varchar))'
ELSE 'TaskSubType Is Null'
END
exec sp_executesql #SQL
, N'#ID Int, #TaskType varchar(10), #TaskSubType tinyint'
, #ID, #TaskType, #TaskSubType
, #ID = #ID OUTPUT
RETURN #ID
END
When I call:
PRINT dbo.GetID('ABC123')
I get the error:
Only functions and some extended stored procedures can be executed from within a function.
Problem is that you cannot use dynamic SQL from within a function and you can't call stored procedures as well. With that solution is, convert your function to a stored procedure.
Also, I don't see why you need a dynamic SQL. Your dynamic SQL part can just be
SELECT #ID = ID
FROM ZCircuitFaults
WHERE TaskType = #TaskType AND
CASE WHEN ISNULL(#TaskSubType, '') <> ''
THEN (TaskSubType Is Null OR TaskSubType = CAST(#TaskSubType AS Varchar))
ELSE TaskSubType Is Null
END
and then
RETURN #ID;
EDIT:
Your entire WHERE part can be simplified to below
WHERE TaskType = #TaskType
AND (
TaskSubType Is Null
OR
TaskSubType = ISNULL(CAST(#TaskSubType AS Varchar), '')
)
Per books online, you cannot use dynamic SQL inside a function:
User-defined functions cannot make use of dynamic SQL or temp tables.
Table variables are allowed.
http://msdn.microsoft.com/en-us/library/ms191320.aspx Limitations and Restrictions section. You will need to put this into a stored procedure.
#Rahul is right, you don't need dynamic SQL.
I'm learning sql from a book and I'm trying to write a stored procedure but I don't believe that I'm doing it correctly. Is the following way not valid in Microsoft SQL? If not, when is it valid, if ever?
create procedure dept_count(in dept_name varchar(20), out d_count integer)
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
I get the following error
Msg 156, Level 15, State 1, Procedure wine_change, Line 1
Incorrect syntax near the keyword 'in'.
T-SQL
/*
Stored Procedure GetstudentnameInOutputVariable is modified to collect the
email address of the student with the help of the Alert Keyword
*/
CREATE PROCEDURE GetstudentnameInOutputVariable
(
#studentid INT, --Input parameter , Studentid of the student
#studentname VARCHAR (200) OUT, -- Output parameter to collect the student name
#StudentEmail VARCHAR (200)OUT -- Output Parameter to collect the student email
)
AS
BEGIN
SELECT #studentname= Firstname+' '+Lastname,
#StudentEmail=email FROM tbl_Students WHERE studentid=#studentid
END
In T-SQL stored procedures for input parameters explicit 'in' keyword is not required and for output parameters an explicit 'Output' keyword is required. The query in question can be written as:
CREATE PROCEDURE dept_count
(
-- Add input and output parameters for the stored procedure here
#dept_name varchar(20), --Input parameter
#d_count int OUTPUT -- Output parameter declared with the help of OUTPUT/OUT keyword
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Statements for procedure here
SELECT #d_count = count(*)
from instructor
where instructor.dept_name=#dept_name
END
GO
and to execute above procedure we can write as:
Declare #dept_name varchar(20), -- Declaring the variable to collect the dept_name
#d_count int -- Declaring the variable to collect the d_count
SET #dept_name = 'Test'
Execute dept_count #dept_name,#d_count output
SELECT #d_count -- "Select" Statement is used to show the output
I think it can help you:
CREATE PROCEDURE DEPT_COUNT
(
#DEPT_NAME VARCHAR(20), -- Input parameter
#D_COUNT INT OUTPUT -- Output parameter
-- Remember parameters begin with "#"
)
AS -- You miss this word in your example
BEGIN
SELECT COUNT(*)
INTO #D_COUNT -- Into a Temp Table (prefix "#")
FROM INSTRUCTOR
WHERE INSTRUCTOR.DEPT_NAME = DEPT_COUNT.DEPT_NAME
END
Then, you can call the SP like this way, for example:
DECLARE #COUNTER INT
EXEC DEPT_COUNT 'DeptName', #COUNTER OUTPUT
SELECT #COUNTER
Try this:
create procedure dept_count(#dept_name varchar(20),#d_count int)
begin
set #d_count=(select count(*)
from instructor
where instructor.dept_name=dept_count.dept_name)
Select #d_count as count
end
Or
create procedure dept_count(#dept_name varchar(20))
begin
select count(*)
from instructor
where instructor.dept_name=dept_count.dept_name
end
CREATE PROCEDURE [dbo].[USP_StudentInformation]
#S_Name VARCHAR(50)
,#S_Address VARCHAR(500)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Date VARCHAR(50)
SET #Date = GETDATE()
IF EXISTS (
SELECT *
FROM TB_StdFunction
WHERE S_Name = #S_Name
AND S_Address = #S_Address
)
BEGIN
UPDATE TB_StdFunction
SET S_Name = #S_Name
,S_Address = #S_Address
,ModifiedDate = #Date
WHERE S_Name = #S_Name
AND S_Address = #S_Address
SELECT *
FROM TB_StdFunction
END
ELSE
BEGIN
INSERT INTO TB_StdFunction (
S_Name
,S_Address
,CreatedDate
)
VALUES (
#S_Name
,#S_Address
,#date
)
SELECT *
FROM TB_StdFunction
END
END
Table Name : TB_StdFunction
S_No INT PRIMARY KEY AUTO_INCREMENT
S_Name nvarchar(50)
S_Address nvarchar(500)
CreatedDate nvarchar(50)
ModifiedDate nvarchar(50)
Create this way.
Create procedure dept_count(dept_name varchar(20),d_count integer)
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
try this:
create procedure dept_count( #dept_name varchar(20), #d_count INTEGER out)
AS
begin
select count(*) into d_count
from instructor
where instructor.dept_name=dept_count.dept_name
end
To Create SQL server Store procedure in SQL server management studio
Expand your database
Expand programmatically
Right-click on Stored-procedure and Select "new Stored Procedure"
Now, Write your Store procedure, for example, it can be something like below
USE DatabaseName;
GO
CREATE PROCEDURE ProcedureName
#LastName nvarchar(50),
#FirstName nvarchar(50)
AS
SET NOCOUNT ON;
//Your SQL query here, like
Select FirstName, LastName, Department
FROM HumanResources.vEmployeeDepartmentHistory
WHERE FirstName = #FirstName AND LastName = #LastName
GO
Where, DatabaseName = name of your database
ProcedureName = name of SP
InputValue = your input parameter value (#LastName and #FirstName) and type = parameter type example nvarchar(50) etc.
Source: Stored procedure in sql server (With Example)
To Execute the above stored procedure you can use sample query as below
EXECUTE ProcedureName #FirstName = N'Pilar', #LastName = N'Ackerman';
I’m executing a procedure like this:
EXEC myProcedure #name = 'Smith', #dateDeleted = NULL
I need all the Smith that don’t have a deleted date.
And this is the procedure:
CREATE PROCEDURE [dbo].[myProcedure]
#name VARCHAR(8000) = NULL
,#dateDeleted VARCHAR(8000) = NULL
AS
BEGIN
SET NOCOUNT ON;
WITH t
(name
,dateDeleted
)
AS
(
SELECT DISTINCT
name,dateDeleted FROM mytable
WHERE
(#name IS NULL OR #name = name)
AND (#dateDeleted IS NULL OR CONVERT(DATETIME, #dateDeleted, 102) = dateDeleted)
)
After the execution I have all the Smith but it does not pay any attention to the dateDeleted = NULL .. I ge all the Smiths no matter if they have a deleted date
How can I fix this?
Thanks
In your request if you pass NULL then a condition always true.Try this WHERE clause with COALESCE expression:
WHERE (#name IS NULL OR #name = name)
AND (COALESCE(#dateDeleted, dateDeleted) IS NULL
OR CONVERT(DATETIME, #dateDeleted, 102) = dateDeleted)
You need to set ansi nulls on
Execute:
set ansi_nulls on
And then execute the query.
Here is the explantion for this behaviour
http://msdn.microsoft.com/en-us/library/ms188048.aspx