SQL stored procedure call failed with index out of range - sql

I am trying to execute a stored procedure in SQL Server from my java code. This stored procedure is used in some other language and it was working fine from long back. Now I need to integrate it in my java app. I have 15 columns in my table. When I tried this in my java code, its throwing
com.microsoft.sqlserver.jdbc.SQLServerException: The index 11 is out of range
I also see "Error: 0, SQLState: S1093"
My stored procedure
ALTER PROCEDURE [dbo].[user_input_sp]
#Username VARCHAR(10)=NULL,
#UserKey VARCHAR(50)=NULL,
#ReqTime DATETIME=null,
#ResTime DATETIME=null,
#Req TEXT=null,
#Res TEXT=null,
#condition TEXT=null,
#ID INT=null,
#Address VARCHAR(8000) = NULL,
#Task VARCHAR(50) = NULL,
#Direction INT=0,
#Seq INT=0,
#RR BIT=0,
#Correction VARCHAR(8) = NULL,
#PendingTrans VARCHAR(50) = NULL,
#ForwardID VARCHAR(50) = NULL,
#Command VARCHAR(50) = NULL
AS
DECLARE #TSqno int
#IF #Direction=0
BEGIN
EXECUTE Basp_NewKey 'web_log', #TSqno OUTPUT
Insert into cbscne dbo WebServiceLog( Order, US_Name, US_Key , US_ReqD, US_ResD, US_Req , US_Res, cond, ID ,Address, Task, Command)
values (#TSqno, #Username, #UserKey, #ReqTime, #ResTime, #Req ,#Res, #condition, #ID ,#Address, #Task ,#Command)
END
.......
My java code
public vold addWebServiceLogRequest(UserInput cd){
sessionFactory = sqlServerEMFactory.unwrap(SessionFactory.class);
Session sessionForSave = sessionFactory.openSession();
sessionForSave.beginTransaction();
sessionForSave.doReturningWork(connection-> {
try(CallableStatement cstmt = connection.prepareCall("{call user_input_sp(?,?,?,?,?,?,?,?,?)}")) {
cstmt.setInt("indicator", 0);
cstmt.setString("Username",cd.getInterfaceName());
cstmt.setInt("User_code",cd.getCaseId());
cstmt.setTimestamp("RetrieveDate",cd.getRequestDate());
cstmt.setTimestamp("ReturnDate",cd.getResponseDate());
cstmt.setString("Req",cd.getRequestxml());
cstmt.setString("Res",cd.getResponsexml());
cstmt.setString("Task",cd.getTask());
cstmt.setString("flow",null);
cstmt.execute();
cstmt.close();
connection.close();
return null;
}
});
}

Related

Why ##rowcount returns 0 when more than 1 user access store procedure for insertion

i am using asp.net, i am calling insertion store procedure whihc works fine until one person is inserting but throw error when more than 1 person simultaneously inserts records i.e. ##RowCount stores 0 and returns 0 to application.
USE [CPOCMS]
GO
/** Object: StoredProcedure [dbo].[InsertComplaints] Script Date: 9/24/2014 11:56:13 AM **/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[InsertComplaints]
#ComplaintCode varchar(50),
#ComplaintType_ID smallint,
#RecievingMode_ID smallint,
#Subject varchar(100),
#ComplainantID smallint,
#District_ID smallint,
#AddressedTo varchar(50),
#DiaryNo varchar(50),
#User_ID int,
#Status_ID smallint,
#RecievedDate smalldatetime,
#IGRemarks varchar(MAX) = null,
#PsoRemarks varchar(MAX) =null,
#FinalDecision varchar(250)=null,
#AgainstDist_ID smallint,
#HomePS_ID smallint,
#AgainstPS_ID smallint,
#Name varchar(75),
#DesigID int,
#ForwardedBy smallint,
#SMS_ID int = 0,
#result bit output,
#ID int output
AS
BEGIN
Begin Try
insert into dbo.Complaints
values (
#ComplaintCode,
#ComplaintType_ID,
#RecievingMode_ID ,
#Subject,
#ComplainantID ,
#District_ID ,
#AddressedTo ,
#DiaryNo,
#User_ID,
#Status_ID,
#RecievedDate,
#IGRemarks,
#PsoRemarks,
#FinalDecision,
#AgainstDist_ID,
#HomePS_ID,
#AgainstPS_ID,
#Name ,
#DesigID,
#ForwardedBy,
#SMS_ID
)
Set #result = ##ROWCOUNT
Select #ID= Ident_Current('dbo.Complaints')
End Try
Begin Catch
Set #result=0
End Catch
END
in sql it shows ##Rowcount = 0 and in asp.net it returns #result=0 , why ?
cmd.ExecuteNonQuery();
Boolean Result = Convert.ToBoolean(pResult.Value);
if (Result)
{
int i = Convert.ToInt32(pID.Value);
return i;
}
else
{
return 0;
}
Note: i have removed unnecessary code.

Although I send the parameter I get "Can not insert NULL value..."

I am developing an ADO.NET application. At some point in the DAL I call a stored-procedure named "CREATE_CUSTOMER". Although I set the SHORT_NAME field I still get the
"Msg 515, Level 16, State 2, Procedure CREATE_CUSTOMER, Line 29
Cannot insert the value NULL into column 'SHORT_NAME', table 'MYDB.app.CUSTOMER';
column does not allow nulls. INSERT fails." error.
When I inspect the query with the SQL profiler I get the following SQL runs on the server. As I Copy&Paste it to a new Query Window I still get the same error.
Do I miss something?
declare #p16 int
set #p16=NULL
exec sp_executesql N'[app].[CREATE_CUSTOMER]',
N'#SHORT_NAME nvarchar(11),
#MAIL_NAME nvarchar(18),
#MT_SALESPERSON_ID int,
#CREDIT_LIMIT decimal(1,0),
#CREDIT_LIMIT_CURRENCY_ID int,
#PAYMENT_TYPE_ID int,
#SALES_TERM_ID int,
#FREE_STORAGE_DAY_ID int,
#RISK_GROUP_ID int,
#SECTOR_ID int,
#OCCUPATION_ID int,
#STORAGE_FEE_ID int,
#STATUS smallint,
#IDENTITY int output',
#SHORT_NAME=N'NEW Corp',
#MAIL_NAME=N'NEW Corporation',
#MT_SALESPERSON_ID=3,
#CREDIT_LIMIT=0,
#CREDIT_LIMIT_CURRENCY_ID=1,
#PAYMENT_TYPE_ID=4,
#SALES_TERM_ID=7,
#FREE_STORAGE_DAY_ID=6,
#RISK_GROUP_ID=3,
#SECTOR_ID=13,
#OCCUPATION_ID=16,
#STORAGE_FEE_ID=6,
#STATUS=0,
#IDENTITY=#p16 output
select #p16
And my Stored Procedure is as follows :
CREATE PROCEDURE [app].[CREATE_CUSTOMER]
#SHORT_NAME varchar(250) = NULL,
#MAIL_NAME varchar(500) = NULL,
#MT_SALESPERSON_ID int = NULL,
#CREDIT_LIMIT decimal(18,2) = NULL,
#CREDIT_LIMIT_CURRENCY_ID int = NULL,
#PAYMENT_TYPE_ID int = NULL,
#SALES_TERM_ID int = NULL,
#FREE_STORAGE_DAY_ID int = NULL,
#RISK_GROUP_ID int = NULL,
#SECTOR_ID int = NULL,
#OCCUPATION_ID int = NULL,
#STORAGE_FEE_ID int = NULL,
#STATUS tinyint = NULL,
#IDENTITY INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [app].[CUSTOMER]
([SHORT_NAME],
[MAIL_NAME],
[MT_SALESPERSON_ID],
[CREDIT_LIMIT],
[CREDIT_LIMIT_CURRENCY_ID],
[PAYMENT_TYPE_ID],
[SALES_TERM_ID],
[FREE_STORAGE_DAY_ID],
[RISK_GROUP_ID],
[SECTOR_ID],
[OCCUPATION_ID],
[STORAGE_FEE_ID],
[STATUS],
[CREATE_DATE],
[CREATE_USERID])
VALUES
(#SHORT_NAME,
#MAIL_NAME,
#MT_SALESPERSON_ID,
#CREDIT_LIMIT,
#CREDIT_LIMIT_CURRENCY_ID,
#PAYMENT_TYPE_ID,
#SALES_TERM_ID,
#FREE_STORAGE_DAY_ID,
#RISK_GROUP_ID,
#SECTOR_ID,
#OCCUPATION_ID,
#STORAGE_FEE_ID,
#STATUS,
GETDATE(),
CONTEXT_INFO())
SELECT #IDENTITY = SCOPE_IDENTITY()
END
This SQL code is being generated by the ADO.NET. Actual C# code is :
private static ICustomer CreateCustomer(ICustomer customer, int contextUserId)
{
try
{
string sql = "[app].[CREATE_CUSTOMER]";
SqlConnection conn = null;
using (conn = GetConnection())
{
SetContextInfomationToConnection(conn, contextUserId);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#SHORT_NAME", customer.ShortName);
cmd.Parameters.AddWithValue("#MAIL_NAME", customer.MailName);
cmd.Parameters.AddWithValue("#MT_SALESPERSON_ID", customer.SalesPersonId);
cmd.Parameters.AddWithValue("#CREDIT_LIMIT", customer.CreditLimit);
cmd.Parameters.AddWithValue("#CREDIT_LIMIT_CURRENCY_ID", customer.CreditLimitCurrencyId);
cmd.Parameters.AddWithValue("#PAYMENT_TYPE_ID", customer.PaymentTypeId);
cmd.Parameters.AddWithValue("#SALES_TERM_ID", customer.SalesTermId);
cmd.Parameters.AddWithValue("#FREE_STORAGE_DAY_ID", customer.FreeStorageDayId);
cmd.Parameters.AddWithValue("#RISK_GROUP_ID", customer.RiskGroupId);
cmd.Parameters.AddWithValue("#SECTOR_ID", customer.SectorId);
cmd.Parameters.AddWithValue("#OCCUPATION_ID", customer.OccupationId);
cmd.Parameters.AddWithValue("#STORAGE_FEE_ID", customer.StorageFeeId);
cmd.Parameters.AddWithValue("#STATUS", customer.Status);
SqlParameter prmNewId = new SqlParameter("#IDENTITY", SqlDbType.Int, 4);
prmNewId.Direction = ParameterDirection.Output;
cmd.Parameters.Add(prmNewId);
cmd.ExecuteNonQuery();
int id = prmNewId.Value != DBNull.Value ? (int)prmNewId.Value : -1;
if (id > 0)
{
customer.Id = id;
return customer;
}
else
{
throw new Exception("Can not insert customer record with Id generation");
}
}
}
catch (Exception ex)
{
throw;
}
}
Your code is the equivalent of doing this:
DECLARE #SHORT_NAME nvarchar(11) = N'NEW Corp';
...
EXEC [app].[CREATE_CUSTOMER];
You are just declaring the parameters, never actually passing them to the procedure invocation. Your code should be like this:
exec sp_executesql N'[app].[CREATE_CUSTOMER] #SHORT_NAME, #MAIL_NAME, ...',
N'#SHORT_NAME nvarchar(11),
#MAIL_NAME nvarchar(18),
...',
#SHORT_NAME=N'NEW Corp',
#MAIL_NAME=N'NEW Corporation',
...
You must not only declare the parameters you pass to the batch, you must also use them when you invoke the procedure.
When I inspect the query with the SQL profiler I get the following SQL runs on the server. As I Copy&Paste it to a new Query Window I still get the same error
This sounds suspiciously like you are using a SqlCommand but forgot to set the CommandType to Procedure. the default is Text and will behave exactly as you observed.
Do not assign null values to ur variable, try only with DECLARING it as bellow
DECLARE #SHORT_NAME varchar(250) ,
instead of
#SHORT_NAME varchar(250) = NULL,

Cannot insert to more than one table

I am trying to execute a stored procedure via excel VBA, however the stored procedure only inserts a record into a single table and throws an error message when the other 2 records are to be inserted to their respective tables
The error message is thrown on the VBA side however in SQL management studio there are no errors yet it still only inserts to the single table.
--Edit:
Error message I receive VBA side
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
USE [MainRoads]
GO
/****** Object: StoredProcedure [mruser].[sp_InsertUpdateProject] Script Date: 18/09/2013 3:04:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [mruser].[sp_InsertUpdateProject]
-- Add the parameters for the stored procedure here
--#ProjectRecord_ID numeric(18,0),
#lProjectNumber numeric(18,0),
#sProjectName nvarchar(300),
#sProjectType nvarchar(100),
#sDirectorate nvarchar(300),
#sProjectManager nvarchar(300),
#sContractType nchar(10),
#sProjectDescription nvarchar(max),
#sCurrentPhase nvarchar(50),
#sProjectStartDate date,
#sPlannedCompDate date,
#sReportingPeriod nchar(10),
#sProjectStatusAt date,
#sPSRApprovedBy nvarchar(100),
#sPSRApprovedDate date,
#sProjectOverallHlth text,
#sProjectWrkflwStatus nchar(10),
#sProjectRAGStatus nchar(10),
#sAssessRAG nchar(10),
#sSelectRAG nchar(10),
#sDevelopRAG nchar(10),
#sDeliverRAG nchar(10),
#sOperateRAG nchar(10),
#lTotalOrigBudget decimal(18,2),
#lTotalAppBudget decimal(18,2),
#lActualsLifeToDate decimal(18,2),
#lTotalForecastToComplete decimal(18,2),
#lTotalProjVar decimal(18,2),
#lCommFunding decimal(18,2),
#lStateFunding decimal(18,2),
#lOthFunding decimal(18,2),
#sCommFundType nvarchar(50),
#sStateFundType nvarchar(50),
#sOthFundType nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
Declare #v_recordexist int
Select #v_recordexist = count(*) From Project_Information Where Project_Number = #lProjectNumber
--If record does not exists update record
IF #v_recordexist = 0
BEGIN
INSERT INTO [mruser].[Project_Information] ([Project_Number], [Project_Name], [Project_Type], [Directorate], [Project_Manager],[Contract_Type], [Project_Description], [Current_RO&DS_Phase], [Project_Start_Date],[Planned_Completion_Date], [Reporting_Period], [Project_Status_At], [PSR_Approved_By], [PSR_Approved_Date], [Project_Overall_Health], [Project_Workflow_Status], [Project_RAG_Status], [Date_Inserted] )
values(#lProjectNumber, #sProjectName, #sProjectType, #sDirectorate, #sProjectManager, #sContractType, #sProjectDescription, #sCurrentPhase, #sProjectStartDate, #sPlannedCompDate, #sReportingPeriod, #sProjectStatusAt, #sPSRApprovedBy, #sPSRApprovedDate, #sProjectOverallHlth, #sProjectWrkflwStatus, #sProjectRAGStatus, GETDATE())
--SELECT SCOPE_IDENTITY() as ProjectIDNumber
BEGIN
Insert into [mruser].[Project_Finance] ([Project_Number], [Total_Original_Budget], [Total_Approved_Budget], [Actuals_Life_To_Date], [Total_Forecast_Cost_To_Complete], [Total_Project_Variance], [Commonwealth_Funding], [State_Funding], [Other_Funding], [Commonwealth_Fund_Type], [State_Fund_Type], [Other_Fund_Type]) values (#lProjectNumber, #lTotalOrigBudget, #lTotalAppBudget, #lActualsLifeToDate, #lTotalForecastToComplete ,#lTotalProjVar ,#lCommFunding ,#lStateFunding ,#lOthFunding ,#sCommFundType ,#sStateFundType ,#sOthFundType)
--(strClientID, timeReg, timeValid, bCurrent, durum) VALUES (#strClientID,getdate(),getdate() + 30,'1','1')
Insert into [mruser].[Project_Milestones] ([Project_Number], [Assess_RAG_Status], [Select_RAG_Status], [Develop_RAG_Status], [Deliver_RAG_Status], [Operate_RAG_Status]) values(#lProjectNumber, #sAssessRAG, #sSelectRAG, #sDeliverRAG, #sDevelopRAG, #sOperateRAG)
--Insert into [mruser].[Project_Finance] ([Project_Number], [Total_Original_Budget], [Total_Approved_Budget], [Actuals_Life_To_Date], [Total_Forecast_Cost_To_Complete], [Total_Project_Variance], [Commonwealth_Funding], [State_Funding], [Other_Funding], [Commonwealth_Fund_Type], [State_Fund_Type], [Other_Fund_Type]) values (#lProjectNumber, #lTotalOrigBudget, #lTotalAppBudget, #lActualsLifeToDate, #lTotalForecastToComplete ,#lTotalProjVar ,#lCommFunding ,#lStateFunding ,#lOthFunding ,#sCommFundType ,#sStateFundType ,#sOthFundType)
END
End
Else
BEGIN
update [mruser].[Project_Information] set
[Project_Number] = #lProjectNumber,
[Project_Name] = #sProjectName,
[Project_Type] = #sProjectType,
[Directorate] = #sDirectorate,
[Project_Manager] = #sProjectManager,
[Contract_Type] = #sContractType,
[Project_Description] = #sProjectDescription,
[Current_RO&DS_Phase] = #sCurrentPhase,
[Project_Start_Date] = #sProjectStartDate,
[Planned_Completion_Date] = #sPlannedCompDate,
[Reporting_Period] = #sReportingPeriod,
[Project_Status_At] = #sProjectStatusAt,
[PSR_Approved_By] = #sPSRApprovedBy,
[PSR_Approved_Date] = #sPSRApprovedDate,
[Project_Overall_Health] = #sProjectOverallHlth,
[Project_Workflow_Status] = #sProjectWrkflwStatus,
[Project_RAG_Status] = #sProjectRAGStatus
where [Project_Number] = #lProjectNumber
update [mruser].[Project_Milestones] set
[Project_Number] = #lProjectNumber,
[Assess_RAG_Status] = #sAssessRAG,
[Select_RAG_Status] = #sSelectRAG,
[Develop_RAG_Status] = #sDeliverRAG,
[Deliver_RAG_Status] = #sDevelopRAG,
[Operate_RAG_Status] = #sOperateRAG
where [Project_Number] = #lProjectNumber
UPDATE [mruser].[Project_Finance] set
[Project_Number] = #lProjectNumber,
[Total_Original_Budget] = #lTotalOrigBudget,
[Total_Approved_Budget] = #lTotalAppBudget,
[Actuals_Life_To_Date] = #lActualsLifeToDate,
[Total_Forecast_Cost_To_Complete] = #lTotalForecastToComplete,
[Total_Project_Variance] = #lTotalProjVar,
[Commonwealth_Funding] = #lCommFunding,
[State_Funding] = #lStateFunding,
[Other_Funding] = #lOthFunding,
[Commonwealth_Fund_Type] = #sCommFundType,
[State_Fund_Type] = #sStateFundType,
[Other_Fund_Type] = #sOthFundType
where [Project_Number] = #lProjectNumber
END
End
Turns out that it was due to not referencing the IDENTITY on the primary table.
I passed SCOPE_IDENTITY() to a variable and now it all works without a hitch.

sp_executesql bug?

Why I get error when call my stored procedure using sp_executesql?
Doesn't works.
exec sp_executesql N'sp_clnt_regional_experts_territories',
N'#action nvarchar(3), #regional_expert_id int,#region_id int,#territory_id int',
#action = N'SEL',
#regional_expert_id = 2,
#region_id = -1,
#territory_id = -1
Procedure or function 'sp_clnt_regional_experts_territories' expects
parameter '#action', which was not supplied.
Works fine:
EXEC sp_clnt_regional_experts_territories
#action = N'SEL',
#regional_expert_id = 2,
#region_id = -1,
#territory_id = -1
Where the stored proc is:
ALTER PROCEDURE [dbo].[sp_clnt_regional_experts_territories]
#action NVARCHAR(3),
#regional_expert_id INT = -1,
#region_id INT = -1,
#territory_id INT = -1
Your sp_executesql is wrong .You need to format it like the one below
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #action nvarchar(3)
DECLARE #regional_expert_id int
DECLARE #region_id int
DECLARE #territory_id INT
Set #SQLString=N'EXEC sp_clnt_regional_experts_territories #action,
#regional_expert_id ,#region_id ,#territory_id'
Set #ParmDefinition='#action NVARCHAR(3),
#regional_expert_id INT ,
#region_id INT ,
#territory_id INT '
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#action=N'SEL',
#regional_expert_id=2,
#region_id=-1,
#territory_id=-1
Instead of directly entering everything in one statement ,dissecting your code into different parts helps you find your problems easily .
the error is because you didn't include the parameters right after your stored procedure name, which is required by sp_executesql
exec sp_executesql N'sp_clnt_regional_experts_territories #action,#regional_expert_id ,#region_id ,#territory_id',
N'#action nvarchar(3), #regional_expert_id int,#region_id int,#territory_id int',
#action = N'SEL',
#regional_expert_id = 2,
#region_id = -1,
#territory_id = -1
sp_executesql says of #params:
Is one string that contains the definitions of all parameters that have been embedded in #stmt.
(Emphasis added)
So, any parameters you identify there must also be mentioned in #stmt, as the other answers have pointed out.

Stored Procedure expects parameter: Parameter is shown in profiler ...?

I am calling a stored procedure from a DbContext using SqlQuery(). When I run the query I get the error Procedure or function 'p_Insert_Phones' expects parameter '#Number', which was not supplied. What am I missing here? I see the #Number parameter.
declare #p5 nvarchar(255)
set #p5=NULL
exec sp_executesql N'p_Insert_Phones',
N'#Number int,
#PhoneTypeId int,
#ReturnId nvarchar(255) output',
#Number=0,
#PhoneTypeId=0,
#ReturnId=#p5 output
select #p5
EDIT
Procedure definition
CREATE PROCEDURE [dbo].[p_Insert_Phones]
(
#Number int,
#PhoneTypeId int,
#ReturnId uniqueidentifier out
)
AS
DECLARE #id TABLE(
ReturnColId uniqueidentifier
)
BEGIN TRAN
INSERT INTO Phones ([Number],[PhoneTypeId])
OUTPUT inserted.Id
INTO #id
VALUES (#Number,#PhoneTypeId)
COMMIT TRAN
SET #ReturnId = (SELECT ReturnColId FROM #id)
Please try the following :
this.context.Database.SqlQuery<string>("p_Insert_Phones #Number = {0}, #PhoneTypeId = {1}", 0, 0);
Where this.context is the context you want to use ofcourse. The generic type parameter for the SqlQuery method is the return type of the query result, in your case is a nvarchar which results in a string type.
(Untested, but it's a mockup based on code i used somewhere within one of my projects).
You cannot call a stored procedure that is found in the database. The parameters that you provide will not be found by the stored procedure. I resolved the issue by including the stored procedure as the sql in the DbContext call.
var sqlInsert = "DECLARE #id TABLE(ReturnColId uniqueidentifier) " +
"BEGIN TRAN INSERT INTO Phones " +
"([Number],PhoneTypeId]) " +
"OUTPUT inserted.Id " +
"INTO #id " +
"VALUES (#Number,#PhoneTypeId) " +
"COMMIT TRAN " +
"SET #ReturnId = (SELECT ReturnColId FROM #id)"
var sqlTransaction = context.Database.SqlQuery(type, insertProcedure, parameters.ToArray());
foreach (var record in sqlTransaction) { } // executes the lazy loading in order to
// populate the out parameter.
Guid newId = new Guid(parameters[parameters.Count - 1].Value.ToString());