I am trying to run sql stored procedure from Access form, which is throwing error
procedure or function has too many arguments
while I have only one parameter passing to stored procedure.
I am using sql server 2012.
What's wrong with my code?
ALTER Procedure [dbo].[SP_SSIS_pkg_Rfnd_BSP] (#ExcelFilePath sql_variant)
As
begin
DECLARE #FolderName nvarchar(128) = 'Import_RAData_BSP'
DECLARE #ProjectName nvarchar(128) = 'SSIS_Rfnd_App_BSP'
DECLARE #PackageName nvarchar(260) = 'pkg_Rfnd_BSP.dtsx'
DECLARE #LoggingLevel varchar(16) = 'Basic'
DECLARE #Use32BitRunTime bit = 0
DECLARE #ReferenceID bigint = NULL
DECLARE #ObjectType smallint = 50
DECLARE #ExecutionID bigint
Set NOCOUNT ON
/* Call the catalog.create_execution stored procedure
to initialize execution location and parameters */
Exec SSISDB.catalog.create_execution
#package_name = #PackageName
,#execution_id = #ExecutionID Output
,#folder_name = #FolderName
,#project_name = #ProjectName
,#use32bitruntime = #Use32BitRunTime
,#reference_id = #ReferenceID
/* Populate the #ExecutionID parameter for OUTPUT */
Select #ExecutionID As Execution_Id
/* Create a parameter (variable) named #Sql */
Declare #logging_level smallint
/* Decode the Logging Level */
Select #logging_level = Case
When Upper(#LoggingLevel) = 'BASIC'
Then 1
When Upper(#LoggingLevel) = 'PERFORMANCE'
Then 2
When Upper(#LoggingLevel) = 'VERBOSE'
Then 3
Else 0 /* 'None' */
End
/* Call the catalog.set_execution_parameter_value stored
procedure to update the LOGGING_LEVEL parameter */
Exec SSISDB.catalog.set_execution_parameter_value
#ExecutionID
,#object_type = 30
,#parameter_name = N'ExcelFilePath'
,#parameter_value = #ExcelFilePath
/* Call the catalog.set_execution_parameter_value stored
procedure to update the LOGGING_LEVEL parameter */
Exec SSISDB.catalog.set_execution_parameter_value
#ExecutionID
,#object_type = #ObjectType
,#parameter_name = N'LOGGING_LEVEL'
,#parameter_value = #logging_level
/* Call the catalog.start_execution (self-explanatory) */
Exec SSISDB.catalog.start_execution #ExecutionID
end
VBA Function to execute stored procedure
Function Import_RA_Data(ByVal FileName As String, FName As String)
On Error GoTo ErrHandler:
Dim objConn As New ADODB.Connection
Dim objCmd As New ADODB.Command
Dim objParm As New ADODB.Parameter
Dim objRs As New ADODB.Recordset
Dim FilePath As String
' Set CommandText equal to the stored procedure name.
objCmd.CommandText = "SP_SSIS_pkg_Rfnd_BSP"
objCmd.CommandType = adCmdStoredProc
' Connect to the data source.
Set objConn = GetNewConnection
objCmd.ActiveConnection = objConn
' Automatically fill in parameter info from stored procedure.
objCmd.Parameters.Refresh
objParm.Value = FilePath
Set objParm = objCmd.CreateParameter("#ExcelFilePath", adVariant, adParamInput, , objParm.Value)
objCmd.Parameters.Append objParm
objRs.CursorType = adOpenStatic
objRs.CursorLocation = adUseClient
objRs.LockType = adLockOptimistic
objRs.Open objCmd
' Execute once and display...
Set objRs = objCmd.Execute
'clean up
objRs.Close
objConn.Close
Set objRs = Nothing
Set objConn = Nothing
Set objCmd = Nothing
Set objParm = Nothing
Exit Function
ErrHandler:
'clean up
If objRs.State = adStateOpen Then
objRs.Close
End If
If objConn.State = adStateOpen Then
objConn.Close
End If
Set objRs = Nothing
Set objConn = Nothing
Set objCmd = Nothing
Set objParm = Nothing
If Err <> 0 Then
MsgBox Err.Source & "-->" & Err.Description, vbCritical, "Error"
End If
End Function
It looks like this code is adding the same parameter twice. The Refresh method populates the parameter collection and then you are manually adding the same parameter again, and only one of the parameter values is set.
' Automatically fill in parameter info from stored procedure.
objCmd.Parameters.Refresh
objParm.Value = FilePath
Set objParm = objCmd.CreateParameter("#ExcelFilePath", adVariant, adParamInput, , objParm.Value)
objCmd.Parameters.Append objParm
One way to fix is to remove the CreateParameter:
objCmd.Parameters.Refresh
objCmd.Parameters("#ExcelFilePath").Value = FilePath
Alternatively, you could remove the Refresh and create the parameters manually. The advantage of this method is it avoids the extra round trip to retrieve parameter meta-data.
Set objReturnCodeParm = objCmd.CreateParameter("#RETURN_CODE", adInteger, adParamReturnValue)
objCmd.Parameters.Append objReturnCodeParm
Set objParm = objCmd.CreateParameter("#ExcelFilePath", adVariant, adParamInput, , FilePath)
objCmd.Parameters.Append objParm
Note that sp_ should be avoided as a stored procedure name prefix. That prefix is used to designate system stored procedures.
EDIT:
catalog.start_execution will execute the package asynchronously so the wrapper proc will finish before it completes. If you want to wait, add a SYNCHRONIZED parameter like the example below. Be aware that the default ADO command timeout is 30 seconds so you may need to increase the value by setting objCmd.CommandTimeout to a higher value, or zero for no timeout.
EXEC SSISDB.catalog.set_execution_parameter_value
#ExecutionID
,#object_type = #ObjectType --this must be 50
,#parameter_name = N'SYNCHRONIZED'
,#parameter_value = 1;
Related
I have a problem with return output parameter from mysql stored procedure to VBA macro.
I wrote this mysql stored procedure InsertProduct to insert new product into database:
DELIMITER $$
CREATE PROCEDURE `InsertProduct`(IN `p_modelno` VARCHAR(40), IN `p_name` VARCHAR(120), OUT `p_last_id` BIGINT)
BEGIN
INSERT INTO product (product_id, name, model_no) VALUES (null, p_name, p_modelno);
SET p_last_id = LAST_INSERT_ID();
END$$
DELIMITER ;
When I test this procedure in phpmyadmin, it returns Last_Insert_ID correctly (for example - new record got the ID 4454, it display p_last_id=4454), see this image:
phpmyadmin testing procedure returns correct ID
Then I have an userform in excel with two text boxes (txtModelNo, txtName) as a front-end to save new product into database. I've written VBA macro to save the product into database and then I want to dipslay msgbox with this last insert record ID. Here is the problem, p_last_id in macro always returns 0 ...
Code in VBA for running this stored procedure and use this output parameter:
Sub InsertProduct()
Dim cnSqlConn As New ADODB.Connection
cnSqlConn.Connectionstring = "DSN=XXX"
cnSqlConn.Open
Dim cmd As New ADODB.Command
With cmd
.ActiveConnection = cnSqlConn
.CommandType = adCmdStoredProc
.CommandText = "InsertProduct"
.CommandTimeout = 15
End With
cmd.Parameters.Append cmd.CreateParameter("p_modelno", adVarChar, adParamInput, 40, Me.txtModelNo)
cmd.Parameters.Append cmd.CreateParameter("p_name", adVarChar, adParamInput, 120, Me.txtName)
cmd.Parameters.Append cmd.CreateParameter("p_last_id", adInteger, adParamOutput, 11)
cmd.Execute lngResult
Msgbox cmd.Parameters("p_last_id") /****** HERE COMES THE PROBLEM - IT ALWAYS RETURNS 0 !! *******/
Set cmd = Nothing
cnSqlConn.Close
Set cnSqlConn = Nothing
End Sub()
I've read many articles about this topic, but nothing helps. Thanks in advance for any advice.
OK, I rewrite the procedure without output parameter:
DELIMITER $$
CREATE PROCEDURE `InsertProduct`(IN `p_modelno` VARCHAR(40), IN `p_name` VARCHAR(120))
BEGIN
INSERT INTO product (product_id, name, model_no) VALUES (null, p_name, p_modelno);
SELECT LAST_INSERT_ID() as last_id FROM product;
END$$
DELIMITER ;
VBA procedure code:
Sub InsertProduct()
Dim cnSqlConn As New ADODB.Connection
cnSqlConn.Connectionstring = "DSN=XXX"
cnSqlConn.Open
Dim cmd As New ADODB.Command
With cmd
.ActiveConnection = cnSqlConn
.CommandType = adCmdStoredProc
.CommandText = "InsertProduct"
.CommandTimeout = 15
End With
cmd.Parameters.Append cmd.CreateParameter("p_modelno", adVarChar, adParamInput, 40,
Me.txtModelNo)
cmd.Parameters.Append cmd.CreateParameter("p_name", adVarChar, adParamInput, 120,
Me.txtName)
dim rstProduct as new ADODB.Recordset
set rstProduct = cmd.Execute
Msgbox rstProduct.Fields("last_id").Value /* displays the correct value */
rstProduct.Close
set rstProduct = nothing
Set cmd = Nothing
cnSqlConn.Close
Set cnSqlConn = Nothing
End Sub()
is it possible to insert/update data into SQL Server tables from Access front end? If so how?
I have a linked sql server table in access db which I want to update using an unbound access form, what is the best way to doing this?
Not sure why it would delete on exiting the database, unless it isn't committing the transaction, though not sure how you would actually do this, maybe something in the connection string to the table.
A very simplistic stored procedure route would look like this:
Create your stored procedure:
CREATE PROCEDURE usp_SimpleUpdateExample
-- Add the parameters for the stored procedure here
#NewValue int,
#WhereCriteria1 int,
#WhereCriteria2 varchar(10),
#Ret int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
BEGIN TRY
BEGIN TRANSACTION
UPDATE tbl_YourTable
SET UpdatedField = #NewValue
WHERE FirstCriteriaField = #WhereCriteria1
And SecondCriteriaField = #WhereCriteria2
SET #Ret = ##ROWCOUNT
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF ##trancount > 0 ROLLBACK TRANSACTION
SET #Ret = -1
END CATCH
END
Create a function to call the procedure:
Function UpdateData(iNewValue As Integer, iCrtieria1 As Integer, _
strCriteria2 As String) As Long
On Error GoTo Err_Handle
Set cnn = CreateObject("ADODB.Connection")
cnn.ConnectionString = "DRIVER={SQL Server};SERVER=ServerName;" _
& "DATABASE=DatabaseName;Trusted_Connection=Yes"
cnn.Open cnn.ConnectionString
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.usp_SimpleUpdateExample"
cmd.CommandTimeout = 0
Set param = cmd.CreateParameter("#NewValue", adInteger, _
adParamInput, , iNewValue)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("#WhereCriteria1", 20, _
adParamInput, , iCrtieria1)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("#WhereCriteria2", adVarChar, _
adParamInput, , strCriteria2)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("#Ret", adInteger, adParamOutput)
cmd.Parameters.Append param
cmd.Execute
UpdateData = cmd.Parameters("#Ret")
Exit_Proc:
Set cnn = Nothing
Set cmd = Nothing
Set param = Nothing
Exit Function
Err_Handle:
' msgbox with details or whatever error handle you use
AllocatePymt = -1
GoTo Exit_Proc
End Function
The stored procedure (and in turn the function) return the number of rows updated (or with an INSERT the number of new rows) or returns -1 if an error occurs; calling it would be something like:
l = UpdateData(52,1234,"FooBar")
SelectCase l
Case Is > 0
msgbox "Updated " & l & " rows"
Case 0
Msgbox "No rows updated, but no error"
Case Else
Msgbox "An error occurred, the transaction was rolled back"
End Select
This all works in Access 2007 and SQL Server 2005, which is all I have available.
MySql IN Parameter - Does a VarChar IN Parameter val need to be single quoted when used in Stored Procedure?
I have created my classic ASP code just like normal but I am not getting the column to update.
Do I need to quote a VarChar parameter?
DELIMITER $$
DROP PROCEDURE IF EXISTS `usp_update_map_record` $$
CREATE DEFINER=`ddddddd`#`%` PROCEDURE `usp_update_map_record`(
IN p_intGrillId INT(10),
IN p_intPartId INT(10),
IN p_ManRef VARCHAR(10)
)
BEGIN
UPDATE parts_map SET manualref = 'p_ManRef' WHERE grillid = p_intGrillId AND partid = p_intPartId;
END $$
DELIMITER ;
VBSCRIPT PORTION:
With comm
.ActiveConnection = conn
.CommandType = adCmdStoredProc
.CommandText = "usp_update_map_record"
.Parameters.Append .CreateParameter("p_intGrillId", adInteger, adParamInput, 10, intGrillId)
.Parameters.Append .CreateParameter("p_intPartId", adInteger, adParamInput, 10, CIntPartId)
.Parameters.Append .CreateParameter("p_ManRef", adVarChar, adParamInput, 10, strManualRef)
.Execute
End With
Also I tested all 3 values and they are not empty.
Thanks.
This is incorrect:
UPDATE parts_map SET manualref = 'p_ManRef'
^-- ^--
The quotes turn that "field" into a string. - you're not comparing two fields, you're comparing the manualref field against a string whose value happens to be the NAME of a parameter for your sproc.
Try:
UPDATE parts_map SET manualref = #p_ManRef
^--- variable/parameter indicator
I posted a question 4 months ago at Store old data in one column and update new data in another column within same table.
Now, I'm working on the codes again and here is my problem. After I clicked the "Update" button on the web page, the old (previous) LastName did not store in the Alias column. In fact, the new LastName is stored in both LastName (for new LastName) and Alias (supposedly for previous LastName) columns. I need the old LastName to be kept in the Alias column. Please review below and see what I did wrong. Thanks in advance!
Stored Procedure
ALTER PROCEDURE [dbo].[KeepAliasName]
#PeopleID int,
#LastName varchar(25)
AS BEGIN
UPDATE People
SET Alias = LastName,
LastName = #LastName
WHERE CAST(PeopleID AS Varchar(25)) = #PeopleID
END
Codes that call the Stored Procedure
Dim oCmd1
Dim ln
Dim retCount
Set oCmd1 = Server.CreateObject("ADODB.Connection")
Set oCmd1 = Server.CreateObject("ADODB.Command")
''' EXECUTE THE COMMAND TO CREATE THE RECORDSET
With oCmd1
.ActiveConnection = Connect
.Commandtext = "KeepAliasName"
.CommandType = adoCmd1StoredProc
.Parameters.Append .CreateParameter("#PeopleID", adInteger, adParamInput, 25)
.Parameters("#PeopleID") = pID 'some Employee you get from your code
.Parameters.Append .CreateParameter("#LastName", adVarChar, adParamInput, 25)
.Parameters("#LastName") = lastnameVal 'some Employee's name you get from your code
.Execute ln, , adExecuteNoRecords
End With
Set oCmd1 = Nothing
Well unless there's a Doh moment e.g. setting new last name to old last name, y=th only explanation is the dbms is executing the two sets in reverse order!
Easy to find out though.
ALTER PROCEDURE [dbo].[KeepAliasName]
#PeopleID int,
#LastName varchar(25)
AS BEGIN
UPDATE People
SET Alias = LastName
WHERE CAST(PeopleID AS Varchar(25)) = #PeopleID
UPDATE People
SET LastName = #LastName
WHERE CAST(PeopleID AS Varchar(25)) = #PeopleID
END
I'm exploring full text index searching using SQL Server 2008 and encounter two sets of errors.
It stems from a a stored procedure I call with VBScript which generates would generate search hit list recordset. The stored procedure runs fine in SQL Server Management studio and basically generates a search hit list. Arguments are keyword, and style for highlighting.
Initially error:
Error One: ADODB.Recordset error '800a0e78 Operation is not allowed when the object is closed
at the If not recordset.EOF line in the to ASP code. Then a bit of reading and searching pointed having SET NOCOUNT ON; especially when referencing temporary tables (KB235340).
However when I specify SET NOCOUNT ON I get the error listed in "error two". NB regarding permissions I have EXECUTE permission assigned to the account running the stored procedure to highlight the search hits.
Error Two: Microsoft OLE DB Provider for SQL Serve error '80040e14'
The user does not have permission to perform this action
Error Two occurs when add the SET NOCOUNT ON.
ASP Code: Line causing the error is highlighted
Dim cmd
Dim newParameter
Dim recordset
Dim SearchTerm
Dim Style
SearchTerm = ""
SearchTerm = Request("searchTerm")
Style = "background-color:yellow; font-weight:bold"
Dim objConnectionMICenter
Set objConnectionMICenter = Server.CreateObject("ADODB.Connection")
objConnectionMICenter.Open Session("ConnectMICenter")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = objConnectionMICenter
' Define the stored procedure's inputs and outputs
' Question marks act as placeholders for each parameter for the
' stored procedure
cmd.CommandType = 4 ' adCmdStoredProc
cmd.CommandText = "HelpAndCalculationNoteHighlight"
'--- Create and append parameter for SearchTerm
Set newParameter = cmd.CreateParameter("SearchTerm",203 ,1,100,SearchTerm)
cmd.Parameters.Append newParameter
'--- Create and append parameter for SearchTerm
Set newParameter = cmd.CreateParameter("Style",203 ,1,200,Style)
cmd.Parameters.Append newParameter
Set recordset = cmd.Execute()
**If not recordset.EOF Then**
While Not recordset.EOF
response.Write "<div>" & recordset.Fields("Snippet") & "</div>"
recordset.MoveNext
Wend
end if
Response.Write strPreviewContents
Set objConnectionMICenter = Nothing
Set newParameter = Nothing
Set cmd = Nothing
recordset.Close
Set recordset = Nothing
Stored Procedure:
ALTER PROCEDURE [dbo].[HelpAndCalculationNoteHighlight]
#SearchTerm nvarchar(100),
#Style nvarchar(200)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
CREATE TABLE #match_docs
(
doc_id bigint NOT NULL PRIMARY KEY
);
INSERT INTO #match_docs
(
doc_id
)
SELECT DISTINCT
id
FROM IntegratedHelpNotes_ChildSectionPage
WHERE FREETEXT
(
content,
#SearchTerm,
LANGUAGE N'English'
);
-- Begin Second Block
DECLARE #db_id int = DB_ID(),
#table_id int = OBJECT_ID(N'IntegratedHelpNotes_ChildSectionPage'),
#column_id int =
(
SELECT
column_id
FROM sys.columns
WHERE object_id = OBJECT_ID(N'IntegratedHelpNotes_ChildSectionPage')
AND name = N'content'
);
-- Begin Third Block
SELECT
s.id,
MIN
(
N'...' + SUBSTRING
(
REPLACE
(
c.content,
s.Display_Term,
N'<span style="' + #Style + '">' + s.Display_Term + '</span>'
),
s.Pos - 512,
s.Length + 1024
) + N'...'
) AS Snippet
FROM
(
SELECT DISTINCT
c.id,
w.Display_Term,
PATINDEX
(
N'%[^a-z]' + w.Display_Term + N'[^a-z]%',
c.content
) AS Pos,
LEN(w.Display_Term) AS Length
FROM sys.dm_fts_index_keywords_by_document
(
#db_id,
#table_id
) w
INNER JOIN dbo.IntegratedHelpNotes_ChildSectionPage c
ON w.document_id = c.id
WHERE w.column_id = #column_id
AND EXISTS
(
SELECT 1
FROM #match_docs m
WHERE m.doc_id = w.document_id
)
AND EXISTS
(
SELECT 1
FROM sys.dm_fts_parser
(
N'FORMSOF(FREETEXT, "' + #SearchTerm + N'")',
1033,
0,
1
) p
WHERE p.Display_Term = w.Display_Term
)
) s
INNER JOIN dbo.IntegratedHelpNotes_ChildSectionPage c
ON s.id = c.id
GROUP BY
s.id;
DROP TABLE #match_docs;
END;
The sys.dm views you use require elevated permissions
sys.dm_fts_parser = sysadmin
sys.dm_fts_index_keywords_by_document = CREATE FULLTEXT CATALOG
As you mentioned, you are using 2 different sets of credentials.
You are sysadmin in SSMS and plain user from vb script.
You can try "EXECUTE AS OWNER" in the stored procedure. Or try wrapping sys.dm_fts_parser in a view in master (also with EXECUTE AS OWNER)