MS SQL get values after INSERT - sql

I am facing an issue where I need to calculate some data based on existing data, then insert that data and finally, return it to an Excel file using VBA.
I have successfully been able to create a stored procedure that returns a table of values after inserting:
[...]
INSERT INTO [ExcelRGA] (RM_prefix, RM_suffix, editing, createdBy, editedBy) values (#RM_prefix, #RM_suffix, 1, #user, #user);
DECLARE #tab table (RM varchar(20))
INSERT #tab SELECT (#RM_prefix +'-' + right('00' + #RM_suffix, 3)) as 'RM';
SELECT * FROM #tab
END
and this works! However, I am unable to get the values it is returning using VBA
Set oRS = New ADODB.Recordset
Set cmd = New ADODB.Command
Dim objRec As Object
cmd.ActiveConnection = oCon
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.newRM"
cmd.Parameters.Refresh
cmd.Parameters("#user").Value = "john"
Set oRS = cmd.Execute()
but I try to do something like
while not oRS.eof
....
wend
get an error message stating that the recordset is closed and I cannot do my thing.
All I am trying to do is secure the information that I have computed (RM_prefix and RM_suffix), insert them into my table and return them to my Excel file.
If there is a way to do this without using a store procedure (such as a function) that would also be great!
Please keep in mind that this is a multi-user environment, so generating the values in Excel, sending them to the SQL server for an insert doesn't give a 100% guarantee regarding the uniqueness of said data.
Thank you all for your precious help and inputs!
Peter

You need something like this -
Private Function GetIDENTITY() As Long
oRS.Open "SELECT ##identity AS NewID", oCon
If Not IsNull(oRS.Fields("NewID")) Then
GetIDENTITY = oRS.Fields("NewID"): oRS.Close
Else
MsgBox "Error: Identity value not returned.", vbCritical
End
End If
End Function

Actually, the issue was coming from the SQL Stored Procedure. I've added
SET NOCOUNT ON;
right before the
INSERT INTO [ExcelRGA] (RM_prefix, RM_suffix, editing, createdBy, editedBy) values (#RM_prefix, #RM_suffix, 1, #user, #user);
And it has solved my problem! I can now browse the recordset in VBA.
Thank you all for your help and inputs!

Related

INSERT statement status in VBA using ADODB

Say i have a table in Excel:
TableA:
ID,
Name,
Work,
DOB
I have an insert query like:
Insert into TableA(ID,Name,Work,DOB) values (....);
I have created the code to upload this data into SQL Server database using ADODB
The upload works fine but i am trying to have it fill the status of the upload such (Pending, Successful) next to each row. Is there any way to do it?
The ending part of my code is:
For lp = 0 To qryindex - 1 'this loop is used to get query from the array which is stored in previous loop
con.Open 'open the connection
con.Execute qryary(lp), dbfailonerror ' execute the query one by one according to index value
oldValue = Application.ActiveCell.Value
con.Close
Next lp
MsgBox "Data Updated Successfully"
ThisWorkbook.RefreshAll
I need it to update the coulmn(F) as each query in the array is successfully posted

insert form data into database using stored procedure in classic asp

I have a form. Its data must be inserted into database (sql server 2008). I have written procedure to insert. How can i insert form data using stored procedure in classic ASP? Need some help as am new to asp and ado.
ALTER PROCEDURE INSERTVALUE
#COMPANY_ID INT ,
#COMPANY_NAME VARCHAR(20),
#SALES_REP VARCHAR (20),
#CONTRACT_ADMIN VARCHAR (20)
AS
BEGIN
INSERT INTO [form].[dbo].[COMPANY]
([COMPANY_ID]
,[COMPANY_NAME]
,[SALES_REP]
,[CONTRACT_ADMIN])
VALUES (#COMPANY_ID,#COMPANY_NAME,#SALES_REP,#CONTRACT_ADMIN);
END
GO
Edit (originally and wrongly posted as answer)
I tried to execute the following code but error occurs. ADODB.Command error '800a0bb9' Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another. /AddForm.asp, line 15 –
set rs=Server.CreateObject("ADODB.recordset")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cnn
sql = " SELECT * FROM COMPANY"
rs.Open sql, cnn
If Request("submit") <> "" Then
cmd.CommandText = "INSERTVALUE"
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter("#COMPANY_ID",adint,adParamInput,10,Request.form("CompanyId"))
cmd.Parameters.Append cmd.CreateParameter("#COMPANY_NAME",advarchar,adParamInput,10, Request.form("company_name"))
cmd.Parameters.Append cmd.CreateParameter("#SALES_REP",advarchar,adParamInput,10,Request.form("sales_rep"))
cmd.Parameters.Append cmd.CreateParameter("#CONTRACT_ADMIN",advarchar,adParamInput,10, Request.form("contract_admin"))
cmd.Execute
End If
One possible cause of your problems and the tutorial don't tell you (or at least the ones I found didn't): if the adovbs.inc files is not found, it will give you:
ADODB.Comman error '800a0bb9'
Arguments are of the wrong type, are out of acceptable range, or are in conflict
with one another.
I had to explicitly include a copy of it.

VBA ADO single command with Insert and Select query

I'm trying to execute the following SQL statement in an Excel Macro, but it fails to return a valid recordset. I suspect that having both an INSERT and a SELECT in the same statement is the culprit.
strSQL :
DECLARE #PurchOrdersTmpXl_A147 Table( SrNo INT, PONum VARCHAR(255));
INSERT INTO #PurchOrdersTmpXl_A147 (SrNo, PONum)
VALUES (1, 'PO0001968'),
(2, 'PO0000260');
SELECT
XLPO.SrNo [PO Order],
POOrigLine.PURCHID [Orig PO],
POOrigLine.ITEMID [Orig Item],
POOrigLine.Name [Orig Txt]
FROM
dbo.PURCHLINE POOrigLine
INNER JOIN #PurchOrdersTmpXl_A147 [XLPO]
ON POOrigLine.PurchID = XLPO.PONum
WHERE
POOrigLine.PurchStatus != 4
VBA Code
Set ADOConn = New ADODB.Connection
ADOConn.connectionString = strConnect
ADOConn.Open
Set ADOcmd = New ADODB.Command
ADOcmd.ActiveConnection = ADOConn
ADOcmd.CommandText = strSQL
Set ADOrs = ADOcmd.Execute
Debug.Print ADOrs.RecordCount // Gives error "Operation Not Allowed when object is closed"
Any help?
Thanks in advance.
Note 1:
I can confirm that this error is because I'm trying to execute an Insert query and a SELECT query in the same command string.
There are no errors if I use a temp table instead of the above table variable and split the command execution (execute the CREATE and INSERT first and then execute the SELECT).
However, as my temp table will never hold more than 20 records, I figure table variables would be more performance effective.
Try this:
Set ADOrs = New ADODB.Recordset
With ADOrs
.CursorLocation = adUseClient
Call .Open(strSQL, ADOConn, , , adCmdText)
If Not (.BOF And .EOF) Then Debug.Print .RecordCount
End With
In this case, the Command object is not needed; you only need the Recordset object.
Is it an option to turn this SQL into a stored procedure? You might have more luck that way as you can hide the other recordsets (which might be why it's closed)
Also is this the whole piece of SQL Code? Why not just select directly from the table? If you want to run this for a set of SrNo/PONum, then there is even more reason to run as a stored proc as you can pass table valued parameters.
http://msdn.microsoft.com/en-us/library/bb675163(v=vs.110).aspx
Here is an example stored proc that works for one set. See the link above for using many sets.
CREATE PROC p_Stuff
#SrNo INt, #PONum VARCHAR(255)
AS
SET NOCOUNT ON
DECLARE #PurchOrdersTmpXl_A147 Table( SrNo INT, PONum VARCHAR(255));
INSERT INTO #PurchOrdersTmpXl_A147 (SrNo, PONum)
VALUES (#SrNo, #PONum);
SELECT
XLPO.SrNo [PO Order],
POOrigLine.PURCHID [Orig PO],
POOrigLine.ITEMID [Orig Item],
POOrigLine.Name [Orig Txt]
FROM
dbo.PURCHLINE POOrigLine
INNER JOIN #PurchOrdersTmpXl_A147 [XLPO]
ON POOrigLine.PurchID = XLPO.PONum
WHERE
POOrigLine.PurchStatus != 4
and then execute as a stored procedure
EXEC p_Stuff 1, 'PO0001968'

Parameterized store procedures in VB.net

I'm getting an error when the 'insertcommand' is executed telling me that I'm missing the parameters for the stored procedure. Do I need to put the parameter names in the Sql statement after the procedure as if I were calling it in SQL? I saw an example online that just added the parameters like I have here, but this doesn't work? I also put the sql state for the stored procedure below the 'AddRepair Sub'
Public Shared Sub AddRepair(ByVal repair As ClubRepair)
Dim conn As SqlConnection = ClubRentalsDB.getconnection
Dim insertcommand As New SqlCommand("AddRepair", conn)
insertcommand.Parameters.AddWithValue("#Name", repair.Name)
insertcommand.Parameters.AddWithValue("#ID", repair.MemberID)
insertcommand.Parameters.AddWithValue("#Phone", repair.PhoneNumber)
insertcommand.Parameters.AddWithValue("#Email", repair.Email)
insertcommand.Parameters.AddWithValue("#Work", repair.WorkToBeDone)
insertcommand.Parameters.AddWithValue("#Specification", repair.Specification)
insertcommand.Parameters.AddWithValue("#SoonestDate", repair.SoonestCompletion)
insertcommand.Parameters.AddWithValue("#PromisedDate", repair.DatePromised)
insertcommand.Parameters.AddWithValue("#ClubType", repair.TypeOfClub)
insertcommand.Parameters.AddWithValue("#GripType", repair.TypeOfGrip)
insertcommand.Parameters.AddWithValue("#NumOfClubs", repair.NumOfClubs)
insertcommand.Parameters.AddWithValue("#SpecialInstructions", repair.SpecialInstructions)
Try
conn.Open()
insertcommand.ExecuteReader()
Catch ex As Exception
MessageBox.Show(messageBad & ex.ToString)
Finally
conn.Close()
End Try
End Sub
USE [ClubRentals]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[AddRepair] (#Name Varchar(50), #ID varchar(20),
#Phone varchar(50),#Email varchar(50), #Work varchar(20),#Specification varchar(MAX),
#SoonestDate date, #PromisedDate Date, #ClubType varchar(50), #Griptype varchar(50),
#NumOfClubs int, #SpecialInstructions varchar(MAX)) as
Insert into ClubRepair(Member_Name,Member_ID,Phone,Email,WorkToBeDone,Specification,
SoonestPossibleCompletion,DatePromised,TypeOfClub, TypeOfGrips ,NumOfClubs,
SpecialInstructions)
values(#Name, #ID, #Phone, #Email, #Work, #Specification,
#SoonestDate, #PromisedDate, #ClubType, #GripType,
#NumOfClubs,#SpecialInstructions)
GO
Confirm that every parameter value you are setting is not Nothing. Parameters with no value can cause the missing parameter error. There's a two-argument version of If() that helps:
insertcommand.Parameters.AddWithValue("#Specification", If(repair.Specification, ""))
this will return repair.Specification if it is not Nothing, and "" otherwise.
also, you should consider using Parameters.Add().Value() instead of .AddWithValue(), like so:
insertcommand.Parameters.Add("#ClubType", SqlDbType.VarChar, 50).Value = If(repair.TypeOfClub, "")
This is really useful when you're working with types other than string.
Try setting sqlcommand commandtype to storedprocedure.
make sure to respect case sensitivity, for an example
insertcommand.Parameters.AddWithValue("#GripType", repair.TypeOfGrip)
is wrong
insertcommand.Parameters.AddWithValue("#Griptype", repair.TypeOfGrip)
is right

SQL Server 2005 Stored Procedure Using Table Variable Doesn't Return ResultSet to VB6 App

I have a stored procedure which selects a single field from a single row (based on a conditional statement) and stores it in a local variable. Based on the value of this field I update the same field in the same row of the table (using the same conditional statement). So the procedure first does a select into a local variable and then later updates the same field of the same row. The procedure then returns a result set via a select on a table variable (I have also attempted using a temporary table). The result set does not contain the variable or field I have updated. It doesn't even include any fields from this table.
The procedure works correctly when called from either Management Studio or from a test C# application. However, when called from my VB6 app the result set is not returned. All database updates are still performed however.
I have tried writing the stored procedure with a transaction and without, with TRY...CATCH and without, and both at the same time. I've tried various combinations of transaction isolation. No exceptions are thrown and the transaction will always commit. I've also used the WITH (NOLOCK) hint on the select statement. If I leave out the table update it will work. If I leave out the assignment to a local variable and instead hard code a value it works. If I simply use the select where I would put the variable it will NOT work.
Interestingly, if I add some random select statement to the procedure it will return that result set. I can even select that same field from the same record I assign to my variable with no issue. But it still will not return my desired result set.
My result set is a select from a table variable which is populated via insert statements using variables set throughout the procedure. There are no table joins at all. I do pass 2 parameters to the procedure - one of which is used in my conditional statement in the original select. But I still get the same behavior when I omit both parameters and hard code values.
I have tried restarting my SQL Server (2005 version 9.0.4053), restarting my machine, i have tried with NOCOUNT ON and OFF, I'm basically out of ideas.
Edit - Details of VB call and stored procedure signature:
I'll try to give as good as a description as I can without publishing actual code. I'm actually posting this for another developer who works with me, so please bear with me.
VB6 Call:
With cmdCommand
.ActiveConnection = cnnConn
.CommandType = adCmdStoredProc
.CommandText = "uspMyStoredProcedure"
.Parameters("#strParam1") = strFunctionParameter1
.Parameters("#bolParam2") = bolFunctionParameter2
.Execute
End With
MyResultSet.CursorLocation = adUseClient
MyResultSet.Open cmdCommand, , adOpenStatic, adLockReadOnly
Stored Procedure signature:
CREATE PROCEDURE uspMyStoredProcedure
#strParam1 NVARCHAR(XX),
#bolParam2 BIT
AS
BEGIN
SET NO COUNT ON
DECLARE #var1 NVARCHAR(XX),
#var2 NVARCHAR(XX),
#var3 NVARCHAR(XX),
#var4 INT,
#var5 BIT
--DECLARATION OF OTHER VARIABLES
DECLARE #varTableVariable TABLE
(
strTblVar1 NVARCHAR(XX) ,
intTblVar2 INT ,
strTblVar3 NVARCHAR(XX) ,
bolTblVar4 BIT ,
datTblVar5 DATETIME
)
SELECT #var1 = t.Field1, #var2 = t.Field2
FROM Table1 t
WHERE t.ID = #strParam1
SELECT #var3 = t2.Field1
FROM Table2 t2
IF (Condition)
BEGIN
SET #var4 = 1
IF (Condition)
BEGIN
--SET SOME VARIABLES
END
ELSE
BEGIN
UPDATE TABLE1
SET Field3 = #var4
WHERE Field1 = #strParam1
END
END
ELSE
BEGIN
IF(Condition)
BEGIN
SELECT #var5 = ISNULL(Condition)
FROM Table3 t3
WHERE t3.Field = #strParam1
--SET SOME MORE VARIABLES
END
END
IF(Condition)
BEGIN
UPDATE Table1
SET Field5 = #SomeVariable
WHERE Field1 = #strParam1
END
INSERT INTO Table4 (Field1, Field2, Field3)
SELECT #SomeVar1, #someVar2, #SomeVar3
FROM SomeOtherTable
WHERE Field3 = #someVariable
IF(Condition)
BEGIN
INSERT INTO #varTableVariable (strTblVar1, intTblVar2,
strTblVar3, bolTblVar4, datTblVar5 )
VALUES (#SomeVar1, #SomeVar2, #SomeVar3, #SomeVar4, #SomeVar5)
END
SELECT *
FROM #varTableVariable
END
So, essentially, the procedure takes two parameters. It carries out a number of simple operations - inserting and selecting data from a couple of different tables, an update to a table and inserting a row into a table variable.
The procedure finishes with a select from the table variable. There's nothing fancy about the procedure, or the call from VB6. As previously stated, the behaviour observed is unusual in that by commenting out certain sections the call and return will work - data is returned. Calling the same procedure from a C#.NET test app works and successfully returns the desired result.
All we manage to get back in the VB6 app is an empty recordset.
Edit 2: We've just found out that if we create an arbitrary table to hold the data to be returned by the final select statement instead of using a table variable, the procedure works...
We discovered that the stored procedure was actually executing twice, due to the way it was being called from VB6:
With cmdCommand
.ActiveConnection = cnnConn
.CommandType = adCmdStoredProc
.CommandText = "uspMyStoredProcedure"
.Parameters("#strParam1") = strFunctionParameter1
.Parameters("#bolParam2") = bolFunctionParameter2
.Execute
End With
MyResultSet.CursorLocation = adUseClient
MyResultSet.Open cmdCommand, , adOpenStatic, adLockReadOnly
The command object 'cmdCommand' is executed the first time with the explicit call as the final line in the 'With' statement, '.Execute'.
What we found was that the last line: 'MyResultSet.Open cmdCommand...' is also implicitly executing the stored procedure a second time.
Since the stored procedure's function is essentially to activate and deactivate an alarm, by executing twice we were getting the activation and deactivation occurring at once and therefore no resultset returned.
Hopefully this might help avoid someone else getting stuck on something like this.