Error When Running Stored Procedure From VBA - sql

I am using VBA to pull information from SQL Server. To not make things complicated read this:
"I have a Stored Procedure in SQL that receiving a Date (#NeededDate as Date) & a comma delimited text (#DelimitedAssets as NVARCHAR(MAX) returns the required results.
When I run my code in VBA, IT WORKS when the text I'm passing (#DelimitedAssets) is not longer than 7000 characters (that's not the exact number but is close). So, rephrasing this: the code works as expected if the string is not big.
But the text I'm passing to the Stored Procedure from VBA adds up to 12000 characters. NVARCHAR should be able to handle that but is not doing it when I pass it from VBA.
IMPORTANT: if I run the same chunk of data (12000 characters) from SQL Server Management Studio, it works perfectly. No errors and the data is ok.
ERROR OCCURS IN LINE:
Set oRecordSet = .Execute
VBA CODE*
Private Function RunMonthlyPricesSP(ByVal strDate As String, ByRef strAssetsDelimted As String, ByRef cnAccounting As Object, ByRef rDestination As Range) As Variant
Dim oCmd As ADODB.Command
Dim oRecordSet As ADODB.Recordset
Dim ActivityParam As ADODB.Parameter
Dim varPrices As Variant
Dim strAction As String
Set oCmd = New ADODB.Command
Set oRecordSet = New ADODB.Recordset
With oCmd
.ActiveConnection = cnAccounting
.CommandType = adCmdStoredProc
.CommandText = "Usp_bondselectionprices"
.Parameters("#NeededDate").Value = strDate
.Parameters("#DelimitedAssets").Value = strAssetsDelimted
Set oRecordSet = .Execute
End With
' Return Array.
' Pending.
End Function
SQL STORED PROCEDURE*
GO
/****** Object: StoredProcedure [dbo].[Usp_bondselectionprices] Script Date: 4/13/2018 5:41:57 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Usp_bondselectionprices] #NeededDate DATE,
#DelimitedAssets VARCHAR(max)
AS
BEGIN
DECLARE #TblBuysSelectionBond BUYSSELECTIONBONDS
INSERT INTO #TblBuysSelectionBond
SELECT *
FROM dbo.Splittext(#DelimitedAssets)
SELECT CASE
WHEN Prices.Price * CurrencyPrices.Price IS NULL THEN Prices.Price
ELSE Prices.Price * CurrencyPrices.Price
END AS Price,
Assets.AssetName
FROM Prices
INNER JOIN Assets
ON Prices.AssetID = Assets.AssetID
INNER JOIN Assets AS Currencies
ON Assets.CurrencyID = Currencies.AssetID
LEFT OUTER JOIN Prices AS CurrencyPrices
ON Currencies.AssetID = CurrencyPrices.AssetID
AND Prices.PriceDate = CurrencyPrices.PriceDate
WHERE prices.PriceDate = #NeededDate
AND assets.InstrumentTypeID = 4
AND Assets.AssetName IN (SELECT *
FROM #TblBuysSelectionBond)
END
FUNCTION CALLED FROM STORED PROCEDURE TO CONVERT TEXT DELIMITED INTO A TABLE*
GO
/****** Object: UserDefinedFunction [dbo].[Splittext] Script Date: 4/13/2018 6:10:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Splittext] (#input AS VARCHAR(max))
RETURNS #Result TABLE(
Value VARCHAR(max))
AS
BEGIN
DECLARE #str VARCHAR(max)
DECLARE #ind bigint
IF( #input IS NOT NULL )
BEGIN
SET #ind = Charindex(',', #input)
WHILE #ind > 0
BEGIN
SET #str = Substring(#input, 1, #ind - 1)
SET #input = Substring(#input, #ind + 1, Len(#input) - #ind)
INSERT INTO #Result
VALUES (#str)
SET #ind = Charindex(',', #input)
END
SET #str = #input
INSERT INTO #Result
VALUES (#str)
END
RETURN
END
Remember, this works for for small string delimited text. So we know that my connection and other arguments are OK.
Thanks,

Ok. I found the solution and it's very, very easy. This is why is so important to check the Watch windows to understand what your Objects (oCMD in this case) has inside.
By default it was taking the parameter #DelimitedAssets as adVarChar. You need to specify that it's not a adVarChar but an adLongVarChar.
.Parameters("#DelimitedAssets").Value = strAssetsDelimted
.Parameters("#DelimitedAssets").Type = adLongVarChar
Once I changed this, everything worked as expected.
Hope this helps.

have you tried to specify type&size?
param.SqlDbType = SqlDbType.VarChar;
param.Size = -1;

Related

sql procedure returns 1 but vb.net gets 0

I have stored procedure which seems to be working fine when executing directly from management studio, but when it comes o vb.net code i always get 0. Can anyone look at that and tell me what is missing here. I read documentation and seems that should work as expected however it is not somehow.
stored procedure:
ALTER PROCEDURE [dbo].[IsPhraseConnectedAlready]
#PhraseId INT,
#KatSubkatId INT,
#WordId INT,
#SubsubkatId INT = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #temp_T_Html_Word_Categories TABLE(Id INT)
DECLARE #temp_T_Html_WordCat_Phrase TABLE(FK_Phrase_ID INT)
DECLARE #temp_T_Html_Phrase TABLE(Id INT, [Name] varchar(max))
IF #SubsubkatId IS NULL
BEGIN
INSERT INTO #temp_T_Html_Word_Categories(Id) SELECT Id FROM T_Html_Word_Categories WHERE FK_KatSubkat_ID = #KatSubkatId And FK_Word_ID = #WordId And FK_Subsubkat_ID IS NULL;
END
ELSE
BEGIN
INSERT INTO #temp_T_Html_Word_Categories(Id) SELECT Id FROM T_Html_Word_Categories WHERE FK_KatSubkat_ID = #KatSubkatId And FK_Word_ID = #WordId And FK_Subsubkat_ID = #SubsubkatId;
END
Declare #Id int;
Select #Id = Id From #temp_T_Html_Word_Categories;
INSERT INTO #temp_T_Html_WordCat_Phrase(FK_Phrase_ID) SELECT FK_Phrase_ID FROM T_Html_WordCat_Phrase WHERE FK_Word_Categorie_ID = #Id;
IF (##ROWCOUNT > 0)
BEGIN
Declare #FK_Phrase_ID int;
--it makes no difference what you SELECT in an EXISTS sub-query as it is just syntactical sugar. (ie Nothing is actually selected.) SELECT * or SELECT 1 ...
WHILE EXISTS(SELECT * FROM #temp_T_Html_WordCat_Phrase)
BEGIN
Select Top 1 #FK_Phrase_ID = FK_Phrase_ID From #temp_T_Html_WordCat_Phrase;
INSERT INTO #temp_T_Html_Phrase(Id, [Name]) SELECT Id, [Name] FROM T_Html_Phrase WHERE Id = #FK_Phrase_ID;
IF (#PhraseId = #FK_Phrase_ID)
RETURN 1
Delete #temp_T_Html_WordCat_Phrase Where FK_Phrase_ID = #FK_Phrase_ID;
END;
END
ELSE
BEGIN
Delete #temp_T_Html_Word_Categories;
RETURN 0
END
RETURN 0
END
This is my visual basic.net code below:
Public Function IsPhraseConnectedAlready(phraseId As Integer, katsubkatid As Integer, wordid As Integer, subsubkatid As Integer?) As Integer
Using con As New SqlConnection(_strcon)
Using cmd As New SqlCommand("IsPhraseConnectedAlready", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#PhraseId", phraseId)
cmd.Parameters.AddWithValue("#KatSubkatId", katsubkatid)
cmd.Parameters.AddWithValue("#WordId", wordid)
If subsubkatid.HasValue Then 'check whether nullable field contain value
cmd.Parameters.AddWithValue("#SubsubkatId", subsubkatid.Value)
Else
cmd.Parameters.AddWithValue("#SubsubkatId", DBNull.Value)
End If
con.Open()
Dim i = CType(cmd.ExecuteScalar(), Integer)
If i = 1 Then
Return True
ElseIf i = 0 Then
Return False
End If
End Using
End Using
End Function
Executed from ssms directly shows it reaches RETURN 1, however with same values passed from vb.net i am getting 0:
in vb.net working with same values:
seems the resolution was to do like this:
instead of this:
RETURN 1 or RETURN 0
make it as:
SELECT 1 or SELECT 0
however to break execution when it reaches first select to add additional return after each SELECT.
Does anyone sees any issues with that? To me it works and wonder why just RETURN was not from vb.net
cmd.ExecuteScalar() will execute the query, and return the first column of the first row in the result set returned by the query. However, you're not returning a column/row, you're just returning a value.
So, either convert RETURN 1 to SELECT 1 or else declare a return parameter in your VB.Net code like so:
...
Dim returnParameter As SqlParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int)
returnParameter.Direction = ParameterDirection.ReturnValue
con.Open()
cmd.ExecuteNonQuery()
Dim i = CType(returnParameter.Value, Integer)
...

Stored Procedure field variable

Aim: To change the field being updated based on an incoming value from the .aspx.vb code
Issue: I believe that the above Aim works, however I am getting an error on the PropertyID (which is alphanumeric) as it says Invalid column name 'S7753' in this case I was updating PropertyID S7753.
.aspx.vb code:
command.CommandText = "spActionUpdateOldestDate"
command.CommandType = CommandType.StoredProcedure
Dim vCheck As String = Session.Item("PropertyID").ToString & "-" & Session.Item("SafeGuardingDate").ToString & "-" & Session.Item("ActionsFieldName").ToString
command.Parameters.AddWithValue("#PropertyID", Session.Item("PropertyID").ToString)
command.Parameters.AddWithValue("#SafeGuardingDate", Session.Item("SafeGuardingDate").ToString)
command.Parameters.AddWithValue("#ActionsFieldName", Session.Item("ActionsFieldName").ToString)
command.ExecuteNonQuery()
command.Parameters.Clear()
Stored Procedure
USE [DB]
GO
/****** Object: StoredProcedure [dbo].[spActionUpdateOldestDate] Script Date: 04/02/2014 14:24:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spActionUpdateOldestDate]
-- spActionUpdateOldestDate '1234','date','field'
-- Add the parameters for the stored procedure here
#PropertyID nvarchar(50)
,#SafeGuardingDate nvarchar(MAX)
,#ActionsFieldName varchar(MAX)
AS
BEGIN
-- add selection for courseID etc.. here
-- print 'UPDATE [TblActionsOldest] SET ' + #ActionsFieldName + ' = ''' + #SafeGuardingDate + ''' WHERE PropertyID = ''' + #PropertyID+ ''''
Execute ('UPDATE [TblActionsOldest] SET ' + #ActionsFieldName + ' = ''' + #SafeGuardingDate + ''' WHERE PropertyID = ''' + #PropertyID+ '''')
add this line before you add the parameters
SqlCommandBuilder.DeriveParameters(command)
Answer at the top, it was syntax for the PropertyID string.

SQL server Nvarchar parameters

I Have created an SP to search against many tables in the db based on string sent form ado
the Vb code
Shared ReadOnly Property Connection() As String
Get
Return ConfigurationManager.ConnectionStrings("ConnString").ConnectionString
End Get
End Property
Function GetData(ByVal SearchKey As String) As DataTable
Dim sqlConn As New SqlConnection(Connection)
Dim ds As New DataSet
Dim sqlCmd As New SqlCommand("Search_List")
Dim sqlAdapter As New SqlDataAdapter
sqlCmd.CommandType = CommandType.StoredProcedure
sqlCmd.Connection = sqlConn
sqlAdapter.SelectCommand = sqlCmd
sqlCmd.Parameters.Add(New SqlParameter("#SearchKey", SqlDbType.NVarChar, 255, ParameterDirection.Input, True, CByte(0), CByte(0), "SearchKey", DataRowVersion.Default, SearchKey))
sqlCmd.Parameters.Add("RerurnValue", SqlDbType.Int)
sqlCmd.Parameters("RerurnValue").Direction = ParameterDirection.ReturnValue
Try
sqlConn.Open()
sqlAdapter.Fill(ds, "Result")
sqlConn.Close()
Catch ex As Exception
Exit Function
End Try
Return ds.Tables("Result")
End Function
and the SQL SP is :
ALTER PROCEDURE [dbo].[Search_List](
#SearchKey NVARCHAR(200)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Rc bigint
DECLARE #Err bigint
set #SearchKey = '%'+#SearchKey+'%'
CREATE
TABLE
#Temp
(
ID BIGINT,
elementType NVARCHAR(10),
NameAr NVARCHAR(255),
NAmeEn NVARCHAR(255),
DescAr NVARCHAR(MAX),
DescEn NVARCHAR(MAX),
URL NVARCHAR(MAX)
)
INSERT INTO #Temp
SELECT
Id
,'C'
,NameAr
,NameEn
,DescAr
,DescEn
,'Counsel.aspx'
FROM
CMS_Councils
Where
(NameAr like #SearchKey
OR
NameEn Like #SearchKey
OR
DescAr Like #SearchKey
OR
DescEn Like #SearchKey)
AND
isnull(Status,0) = 1
select * from #Temp
end
As you can see I have declared argument in VB as Nvarchr and SQL parameter #SearchKey as Nvarchar also if I send english data in #SearchKey search returns correct data, but if I tried to send arabic string in #SearchKey no results appeared knowing that there is arabic data inside the table
Am I missing something?
What Should I do further than that to allow arabic search?
You can try specifying a collation using the COLLATE keyword:
You'd need to specify arabic afterwards, for instance: COLLATE arabic_ci_as
SELECT
Id
,'C'
,NameAr
,NameEn
,DescAr
,DescEn
,'Counsel.aspx'
FROM
CMS_Councils
Where
(NameAr like #SearchKey
OR
NameEn Like #SearchKey
OR
DescAr Like #SearchKey
OR
DescEn Like #SearchKey)
AND
isnull(Status,0) = 1
COLLATE arabic_ci_as

Retrieving output parameter from stored procedure with oledb command vb.net

My stored procedure:
PROCEDURE [dbo].[addMasterTransaksi]
#kodeSuplier varchar(10),
#Total money,
#kodeUser varchar(10),
#isLunas varchar (2),
#Dp money,
#kodeTrans varchar(10) output
AS
BEGIN
Declare #KdTrans as varchar(10);
Declare #Kode as int;
Declare #thisYear as varchar(10);
select #thisyear = RIGHT(YEAR(getDate()),2)
SELECT TOP(1) #KdTrans = SUBSTRING(kodeTransaksi,5,6) FROM TblMasterPembelian WHERE YEAR(Tanggal) = YEAR(getDate()) order by kodeTransaksi desc;
--print #KdTrans
IF #KdTrans IS Null
SET #KdTrans = 'TB'+ #thisYear +'000001'
else
begin
select #Kode = convert(int,#KdTrans);
select #Kode = #Kode + 1;
select #KdTrans = convert(int,#Kode);
select #KdTrans = '00000' + #KdTrans;
select #KdTrans = right(#KdTrans,6)
select #KdTrans ='TB' + #thisYear + #KdTrans
end
SET NOCOUNT ON;
--ke Master Pembelian
INSERT INTO TblMasterPembelian(kodeTransaksi,Tanggal,Total,kodeSuplier,kodeUser,isLunas,DP)
VALUES (#KdTrans,getDate(),#Total,#kodeSuplier,#kodeUser,#isLunas,#Dp)
set #kodeTrans =#KdTrans
--print #kodeTrans
return #kodetrans
END
VB.NET code:
Public Function addMasterPembelianny(ByVal kodesup As String, ByVal total As Long, ByVal kodeUser As String, ByVal isLunas As String, ByVal dp As Long)
Dim kodeTransaksi As String
modKoneksi.bukaKoneksi()
command.Connection = modKoneksi.koneksidb
command.CommandType = CommandType.StoredProcedure
command.CommandText = "addMasterTransaksi"
command.Parameters.Add("#kodeSuplier", OleDbType.VarChar, 10, ParameterDirection.Input).Value = kodesup
command.Parameters.Add("#Total", OleDbType.BigInt, 10, ParameterDirection.Input).Value = total
command.Parameters.Add("#kodeUser", OleDbType.VarChar, 10, ParameterDirection.Input).Value = kodeUser
command.Parameters.Add("#isLunas", OleDbType.VarChar, 2, ParameterDirection.Input).Value = isLunas
command.Parameters.Add("#Dp", OleDbType.BigInt, 10, ParameterDirection.Input).Value = dp
command.Parameters.Add("#kodeTrans", OleDbType.Char, 10)
command.Parameters("#kodeTrans").Direction = ParameterDirection.Output
command.ExecuteReader()
kodeTransaksi = command.Parameters("#kodeTrans").Value
modKoneksi.tutupKoneksi()
Return kodeTransaksi
End Function
I have problem when I want to retrieve parameter from a stored procedure..
When I run that code, there appear an error like this message ..
Conversion failed when converting the varchar value 'TB13000005' to data type int.
Why they said that failed converting to data type int??
What's wrong with my code..?
master help me please..
I believe it is this line in your stored procedure which is causing the error:
return #kodetrans
Stored procedures can only return integers as part of the RETURN statement so the line fails (as #kodetrans is a VARCHAR). You can just remove that line completely...For output parameters, what you have done here:
set #kodeTrans =#KdTrans
In the stored proc is fine and should be sufficient/OK.

get return value from stored procedure without output parameter

I have a vb.net application that inserts records into a db table using a stored procedure that is supposed to return a value. This stored procedure was setup by someone else and initially was linked to a webservice through which my application made the insert and got the return value in the returned xml. I now have access to the db table and not sure how to receive the return value in my vb.net method.
SQl stored procedure snippet;
#urlname varchar(500),
#siteid varchar(16),
#origin varchar(50),
#queryid varchar(25)
AS
SET NOCOUNT ON;
declare #cnt int
declare #serverip varchar(16)
declare #mincnt int
declare #siteservercnt int
select #cnt=COUNT(*) from sites
where urlname=#urlname
if #cnt = 0
begin
insert into sites (urlname,siteid,exported,origin,queryid)
values(#urlname,#siteid,1,#origin,#queryid)
select #siteservercnt = COUNT(*) from siteserverip where siteid=#siteid
if #siteservercnt=0
begin
select top 1 #mincnt=COUNT(*),#serverip=serverip from siteserverip
group by serverip
order by COUNT(*)
select top 1 #mincnt=sitecount,
#serverip=serverip from serveripcounts
order by sitecount
insert into siteserverip values(#siteid,#serverip)
update serveripcounts set sitecount=sitecount+1
where serverip=#serverip
end
end
SELECT siteid from sites
where urlname=#urlname
return
and my vb.net code to do the insert
CommandObj.CommandText = "Getsite"
CommandObj.CommandTimeout = 90
Dim newUrl As String = String.Empty
CommandObj.Parameters.Clear()
Dim m_param As SqlParameter
m_param = CommandObj.Parameters.Add("#urlname", SqlDbType.VarChar, 500)
m_param.Direction = ParameterDirection.Input
m_param.Value = name
m_param = CommandObj.Parameters.Add("#siteid", SqlDbType.VarChar, 16)
m_param.Direction = ParameterDirection.Input
m_param.Value = siteid
m_param = CommandObj.Parameters.Add("#origin", SqlDbType.VarChar, 50)
m_param.Direction = ParameterDirection.Input
m_param.Value = method
m_param = CommandObj.Parameters.Add("#queryId", SqlDbType.VarChar, 25)
m_param.Direction = ParameterDirection.Input
m_param.Value = forumID
Dim recordsAffected As Integer = CommandObj.ExecuteNonQuery
You can use ExecuteScalar to get that value. ExecuteNonQuery returns number of rows affected while you want to get the value generated by last select. You could use ExecuteReader as well but that is useful when your SP might be returning more columns and/or more rows.
'Populate first column and first row value in siteID
Dim siteID As Integer = CommandObj.ExecuteScalar