How to display ADO recordset in Access 2010 - sql

I need some help solving this issue. I'm a VB novice, by the way. I currently have a stored procedure that accepts 3 parameters and when executed returns a temp table. I tested my procedure in SQL and it's working as expected.
I'm using an Access form as my front-end. It is to accept the 3 parameters via 3 text box controls and then executes my procedure 'on click' (User clicks the search button to execute and fire up SQL). The code below accomplishes this, up until it's time to display my recordsets in a table. I'm stuck on how to display my results from my procedure in a table by utlizing ADO properties I'm ok with either displaying the recordset in a datasheet form or inserting them into a table.
The code seems to choke up at this line, where I'm attempting to view my recordset:
rs.Open cmd
Access VB Code
Private Sub cmdExecuteQuery_Click()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim accessionno As String
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
conn.ConnectionString = "Driver={SQL Server};Server=***;Database=***;Uid=****;Pwd=***;"
conn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.NameofStoredProcedure"
cmd.Parameters.Append cmd.CreateParameter("#worksheetno", adVarChar,
adParamInput, 10, Forms!RepeatForm!txtEnterWrkSheetno)
cmd.Parameters.Append cmd.CreateParameter("#name", adVarChar,
adParamInput, 10, Forms!RepeatForm!txtEnterName)
cmd.Parameters.Append cmd.CreateParameter("#year", adVarChar,
adParamInput, 4, Forms!RepeatForm!txtEnterYear)
With rs
.ActiveConnection = conn
.CursorType = adOpenForwardOnly
.CursorLocation = adUseServer
End With
Set rs = cmd.Execute()
DoCmd.OpenForm "frmRepeats", acViewNormal
rs.Open cmd
rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing
End Sub
SQL
CREATE PROCEDURE [dbo].[NameofStoredProcedure] #worksheetno varchar(10),
#name varchar(10), #year varchar(4)
AS
BEGIN
CREATE TABLE #Temp (accessionno varchar (100),
No varchar (100),
worksheetno varchar (10),
name varchar(100),
location varchar (10),
Result varchar (100),
year varchar (4))
INSERT INTO #Temp
SELECT DISTINCT
a.accessionno,
e.name + substring(a.Year, 3,2) + '-' + convert(varchar(10),
c.SampleTestNum) AS No,
a.worksheetno,
b.name,
c.platetext AS Location,
d.finalcomment AS Result,
a.Year
FROM
tb_sample a (nolock), tb_patient b (nolock), tb_plate c (nolock),
tb_finalresult d (nolock), tb_testcode e (nolock)
WHERE
a.sample_id = b.sample_id
and a.sample_id = c.sample_id
and a.sample_id = d.sample_id
and a.test_id = e.test_id
and finalcomment like '%1061%'
and worksheetno = #worksheetno
and e.name = #name
and a.year = #year
ORDER BY No
END
select distinct * from #Temp
drop table #Temp
GO

Related

Parameterized Queries in VBA + ADODB + Oracle

I'm new to working with Oracle 11g and I'm having a lot of issues getting a parameterized query to work smoothly.
this code works:
Dim rs As ADODB.Recordset
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Set con = New ADODB.Connection
With con
.ConnectionString = GetConnection() '<-- the driver here is Driver={Oracle in OraClient11g_home1_32bit}
.Open
End With
Set cmd = New ADODB.Command
With cmd
Set .ActiveConnection = con
.CommandType = adCmdText
.CommandText = "SELECT * FROM MPA_LINEPLAN.REF_BRAND_SEASON_DROP WHERE DROP_ID = ?"
Set prm = .CreateParameter("dropID", adVarChar, adParamInput, 50, "P_SP19_5")
.Parameters.Append prm
Set rs = .Execute
End With
But the actual query I want to run will reference the dropID parameter several times. To get it working, I would have to add the same paramerter over and over. Tell me there's a better way? I tried the following:
With cmd
Set .ActiveConnection = con
.CommandType = adCmdText
.CommandText = "SELECT * FROM MPA_LINEPLAN.REF_BRAND_SEASON_DROP WHERE DROP_ID = :dropID"
Set prm = .CreateParameter("dropID", adVarChar, adParamInput, 50, "P_SP19_5")
.Parameters.Append prm
Set rs = .Execute
End With
But it hits unspecified error when I try to execute into the rs.
Also, assume for my particular case, that stored procs is not the best option (even though it should be the best option :-/)
edit:
The actual query is very long and in the interest of not making you hunt down all the :dropID references, I've reduced it here, but left enough to show the multiple references.
WITH
--...
DropDim AS (
SELECT DROP_ID
, DROP_NAME
, SEASON_ID
, SEASON_NAME
, BRAND_ID
, SEASON_YEAR
, 'DROP_' || substr(DROP_ID, LENGTH(DROP_ID),1) AS LP_Join_Drop
, SEASON_NAME || '_' || SEASON_YEAR AS LP_Join_Season
FROM MPA_LINEPLAN.REF_BRAND_SEASON_DROP
WHERE DROP_ID = :dropID),
--...
LYMap AS
(SELECT DC.DROP_ID
, DC.CHANNEL_ID
, BSD.SEASON_YEAR
, BSD.SEASON_NAME
, BSD.DROP_NAME
, FW.WEEKENDINGDATE AS LY_WEEKENDING_DATE
, FW.YEARWEEK AS LY_YEARWEEK
FROM MPA_LINEPLAN.REF_DROP_CHANNEL DC
INNER JOIN MPA_MASTER.FISCALWEEK FW
ON FW.YEARWEEK BETWEEN DC.LY_START_DT AND DC.LY_END_DT
INNER JOIN MPA_LINEPLAN.REF_BRAND_SEASON_DROP BSD ON BSD.DROP_ID = dc.DROP_ID
WHERE DC.DROP_ID = :dropID),
LLYMap AS
(SELECT DC.DROP_ID
, DC.CHANNEL_ID
, BSD.SEASON_YEAR
, BSD.SEASON_NAME
, BSD.DROP_NAME
, FW.WEEKENDINGDATE AS LLY_WEEKENDING_DATE
, FW.YEARWEEK AS LLY_YEARWEEK
FROM MPA_LINEPLAN.REF_DROP_CHANNEL DC
INNER JOIN MPA_MASTER.FISCALWEEK FW
ON FW.YEARWEEK BETWEEN DC.LLY_START_DT AND DC.LLY_END_DT
INNER JOIN MPA_LINEPLAN.REF_BRAND_SEASON_DROP BSD ON BSD.DROP_ID = dc.DROP_ID
WHERE DC.DROP_ID = :dropID ),
--....
Continue to use the qmarks placeholder and simply use a for loop to append same parameter object. Specifically, qmarks correspond to the position placed in query. Assuming the below query
sql = "SELECT * FROM MPA_LINEPLAN.REF_BRAND_SEASON_DROP" _
& " WHERE DROP_ID = ? AND DROP_ID2 = ? AND DROP_ID3 = ?"
With cmd
Set .ActiveConnection = con
.CommandType = adCmdText
.CommandText = sql
For i = 1 To 3 ' ADJUST TO NUMBER OF PARAMS
Set prm = .CreateParameter("prm" & i, adVarChar, adParamInput, 50, "P_SP19_5")
.Parameters.Append prm
Next i
Set rs = .Execute
End With
Alternatively, turn your query into a stored procedure (avoiding very large SQL string or text file read in VBA), then define one parameter.
Oracle
CREATE OR REPLACE PROCEDURE my_procedure_name(dropID IN VARCHAR2) IS
BEGIN
...long query using dropID (without any symbol)...
END;
/
VBA
With cmd
Set .ActiveConnection = con
.Properties("PLSQLRSet") = TRUE
.CommandType = adCmdText
.CommandText = "{CALL my_procedure_name(?)}"
Set prm = .CreateParameter("prm", adVarChar, adParamInput, 50, "P_SP19_5")
.Parameters.Append prm
Set rs = .Execute
End With
The best solve for this was simply to stop using Oracle's ODBC driver and start using Oracle's OLEDB as a provider instead.
Old connection string:
.ConnectionString = "Driver={Oracle in OraClient11g_home1_32bit};UID=MyUname;PWD=MyPW;DBQ=MyDB;"
New connection string:
.ConnectionString = "Provider=OraOLEDB.Oracle;Data Source=MyDB; User ID=MyUname;Password=MyPW;"
OraOLEDB supports named parameters, which is exactly what I was trying to get to in the first place. Now, I can reference parameter names in the SQL statement with : prefix.
With cmd
Set .ActiveConnection = con
.CommandType = adCmdText
.CommandText = "SELECT * FROM MPA_LINEPLAN.REF_BRAND_SEASON_DROP WHERE DROP_ID =:dropID"
Set prm = .CreateParameter("dropID", adVarChar, adParamInput, 50, "P_SP19_5")
.Parameters.Append prm
Set rs = .Execute
End With
This now works!
Another approach is to use a CTE to have all your scalar parameters and then join back to the table you are interested in:
-- Outer SELECT * due to limitations of ODBC drivers in VBA
SELECT *
FROM
(
WITH lu as (
SELECT ? as drop_id
FROM dual
)
)
SELECT t1.*
FROM mpa_lineplan.ref_brand_season_drop t1
CROSS JOIN lu -- could be inner join or whatever type you are interested in
WHERE t1.drop_id = lu.drop_id
)

Using output parameter from SQL Server stored procedure in Access

I am attempting to get an output variable (the new identity column) from a stored procedure in SQL Server 2008 after executing the procedure from Access 2013 VBA. I don't fully understand all the adodb stuff, and I've tried a number of things from different articles to no avail. Here's where I am with it now...
Stored procedure:
PROCEDURE [proc_NewClient]
#Type INT,
#PhoneIntakeID INT,
#ClientID INT = NULL,
#NewPSID INT = null OUTPUT (2 possible ways to call the proc, one does not produce an output variable)
INSERT INTO tblClientDetails (ClientID, PhoneIntakeID, Client_Status)
VALUES (#ClientID, #PhoneIntakeID, 'Applicant')
DECLARE #NewClientDetailID int
SELECT #NewClientDetailID = SCOPE_IDENTITY()
INSERT INTO tblPS_Psychosocial (ClientDetailID, Client)
VALUES (#NewClientDetailID, #ClientID)
SELECT #NewPSID = SCOPE_IDENTITY()
INSERT INTO tblPS_AbuseHistory (PsychosocialID)
VALUES (#NewPSID)
INSERT INTO tblPS_FamilyHistory(PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_FinancialHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_LegalHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_MedicalHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_PsychiatricHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_SocialHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_SpiritualHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblPS_SubstanceHistory (PsychosocialID) VALUES (#NewPSID)
INSERT INTO tblVocAssessment(ClientDetailID) VALUES (#NewClientDetailID)
And from the form I've got:
Dim cnn As ADODB.Connection
Dim cmd As New ADODB.Command, rs As New ADODB.Recordset, param1 As New ADODB.Parameter, param2 As New ADODB.Parameter, param3 As New ADODB.Parameter, param4 As New ADODB.Parameter
Set cnn = New ADODB.Connection
cnn.ConnectionString = "DRIVER=SQL Server;SERVER=SRV-DB01;DATABASE=TWHClientMgmt;Trusted_Connection=Yes"
cnn.Open cnn.ConnectionString
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "[THEWOMENSHOME\jboyd].proc_NewClient"
Set param1 = cmd.CreateParameter("#Type", adinteger, adparamInput, , 2)
cmd.Parameters.Append param1
Set param2 = cmd.CreateParameter("#PhoneIntakeID", adinteger, adparamInput, , Me.PhoneIntakeID)
cmd.Parameters.Append param2
Set param3 = cmd.CreateParameter("#ClientID", adinteger, adparamInput, , intNewID)
cmd.Parameters.Append param3
Set param4 = cmd.CreateParameter("#NewPSID", adinteger, adParamOutput)
cmd.Parameters.Append param4
rs.open cmd
To this point the code works, the new records are generated, etc. When I run the stored procedure from SQL Server it returns the correct identity column number, but I've tried multiple ways to reference the output in VBA and always end up coming up with a null. How do I reference it here correctly?
To retrieve the value of a stored procedure's OUTPUT parameter you simply .Execute the ADODB.Command and then retrieve the .Value of the corresponding ADODB.Parameter, like so:
cmd.Execute
' retrieve and display the returned OUTPUT parameter value
Debug.Print cmd.Parameters("#NewPSID").Value
Simple DAO solution calling stored procedure:
Public Function RunSqlQuery(q As String) As Variant
Dim cdb As DAO.Database
Dim qdf As DAO.QueryDef
Dim rs As Recordset
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
qdf.Connect = cdb.TableDefs("dbo_Setup").Connect ' your attached table
qdf.SQL = q
qdf.ReturnsRecords = True
Set rs = qdf.OpenRecordset()
RunSqlQuery = rs.Fields(0) ' you also can output more than one parameter from a stored procedure as fields
rs.Close
Set rs = Nothing
Set qdf = Nothing
Set cdb = Nothing
End Function
Now, call the function, define a query the same way you would do at the SQL server:
? RunSQLQuery("DECLARE #param1 varchar(16); exec proc_MyStoredProcedure #param1 OUTPUT; SELECT #param1")

ODBC SQL Server Driver - Conversion failed when converting date and/or time from character string

I am using MS Access VBA to call a stored procedure with paramters passed from Access. I am having issues passing my date variables to the SQL Server Stored procedure:
VBA:
Dim zsql, asql, bsql, gsql As String
Dim searchDeal, searchReviewed As String
Dim searchDate, searchFile As Date
Dim searchType As String
Dim user As String
Dim qdfNew As DAO.QueryDef
Dim myRecordset6 As DAO.Recordset
Dim myDatabase6 As DAO.Database
Dim mycheckRs As DAO.Recordset
DoCmd.SetWarnings False
searchDeal = Me.cboDeal.Value
searchDate = Me.cboStDate.Value
searchFile = Me.cboFile.Value
user = GetUser()
Dim dbconn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim param As New ADODB.Parameter
'' Connect to Data Source - Securities DB - SQL Server
Set dbconn = New ADODB.Connection
dbconn.ConnectionString = "driver=SQL Server;server=R7SQL1;database=SecuritiesDB;trusted_connection=YES"
dbconn.Open dbconn.ConnectionString
Set cmd = New ADODB.Command
cmd.ActiveConnection = dbconn
'' Set CommandText equal to the stored procedure name (spStatementCheck)
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "spAppendActivity"
''cmd.NamedParameters = True 'paramStatementCheck'
cmd.Parameters.Append _
cmd.CreateParameter("#SPstrNGN", adVarChar, adParamInput, 25, searchDeal)
cmd.Parameters.Append _
cmd.CreateParameter("#SPuser", adVarChar, adParamInput, 100, user)
cmd.Parameters.Append _
cmd.CreateParameter("#SPdDateActivity", adDBTimeStamp, adParamInput, 10, searchDate) <--ISSUE
cmd.Parameters.Append _
cmd.CreateParameter("#SPdDateFile", adDBTimeStamp, adParamInput, 10, searchFile) <--ISSUE
--Date format that I am passing should be MM/DD/YYYY
rs.CursorType = adOpenDynamic
rs.CursorLocation = adUseClient
rs.LockType = adLockOptimistic
rs.Open cmd
SQL:
ALTER PROCEDURE [dbo].[spAppendActivity]
#SPsearchDeal as nvarchar(25),
#SPsearchDate as datetime,
#SPsearchFile as datetime,
#SPuser as nvarchar(100)
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
delete from tbl_Activity_Losses;
INSERT into tbl_Activity_Losses ([Date], NGN_Short, FileDate)
Select [Date], NGN_Short, Filedate
from tbl_Master_Rec
where tbl_Master_Rec.[Date] = #SPsearchDate <--Conversion Issue
and tbl_Master_Rec.FileDate = #SPsearchFile <--Conversion Issue
and tbl_Master_Rec.NGN_Short like '%' + #SPsearchDeal + '%'
I get the following error message when the Date is passed using the adDBTimeStamp "[Microsoft][ODBC SQL Server Driver] Conversion failed when converting date and/or time from character string."
I have also tried passing the date as adDBDate and get the error "[Microsoft][ODBC SQL Server Driver] Optional Feature Not Implemented. "
Please let me know if you need more information on the issue I am having
Please note that you will need to construct the datetime string in this format:
adDBDate
Indicates a date value (yyyymmdd) (DBTYPE_DBDATE).
adDBTimeStamp
Indicates a date/time stamp (yyyymmddhhmmss plus a fraction in billionths) (DBTYPE_DBTIMESTAMP).
adDBDate and adDBTimeStamp

VBA How do you pass DATE as parameter to stored procedure

Currently I pass the date parameter as varchar and convert because I got errors with passing a date parameter. I still get errors but its a conversion parameter.
Sub GetPositions() 'xdate As Date
Dim sSQL As String
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Set cmd = New ADODB.Command
Set prm = New ADODB.Parameter
Sheets("Positions").Select
Range("a2:bb999999").ClearContents
Set cn = New ADODB.Connection
cn.CommandTimeout = 300000
cn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=GlobalR;Data Source=SWP"
Dim d As Date
d = "2013/12/03"
cmd.ActiveConnection = cn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "Get9599Delta"
cmd.NamedParameters = True
Set prm = cmd.CreateParameter("#date", adVarChar, adParamInput, 12)
cmd.Parameters.Append prm
cmd.Parameters("#date").Value = "'12/3/2013'"
Set rs = New ADODB.Recordset
rs.Open cmd.Execute ''''I AM GETTING AN ERROR ON THIS LINE THAT READS
''''''''''' CONVERSION FAILED WHEN CONVERTING DATETIME TO CHARACTER STRING
Cells(2, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
here is my stored proc
alter PROC Get9599Delta (#date varchar(12))
AS
DECLARE #d DATETIME
SET #d = CONVERT(DateTime, #date, 104) --convert the varchar to a date
Any idea why I am having this conversion issue?
I'm using Excel 2016 MSO (16.0.8730.2175) 64-bit and my "VBAProject" is referencing "Microsoft ActiveX Data Objects 6.1 Library". I'm running SQL Server Express (64-bit) version 11.0.3156.0 (2012).
My SQL Server database stored procedure has a date parameter with a datetime data type. The stored procedure does not contain SET NOCOUNT ON.
Here's (an edited version of) my code:
Sub ExecuteStoredProcedure(date_ As Date)
Dim connection_ As New ADODB.Connection
connection_.Open "Provider=SQLOLEDB;Data Source=.\SQLEXPRESS;Initial Catalog=not_my_real_database_name;Integrated Security=SSPI"
Dim command_ As New ADODB.Command
With command_
.ActiveConnection = connection_
.CommandType = adCmdStoredProc
.CommandText = "dbo.NotMyRealProcedureName"
.Parameters.Append .CreateParameter("#Date", adDBDate, adParamInput, , date_)
.Execute
End With
End Sub
If you're having similar problems, try commenting or removing all of the code after the connection_.Open ... call. I definitely had problems because of the connection string passed to that call and the error info shown by VBA is so minimal that it was not immediately obvious that my problem wasn't related to the date parameter in my VBA code.
The problem was solved by putting SET NOCOUNT ON at the top of my stored procedure!
try this:
.Parameters.Append .CreateParameter("#date", adDate, adParamInput, , )
# is optional
msdn ( command.CreateParameter (Name, Type, Direction, Size, Value) )
and type of parameter adDBTimeStamp

SQL Parameterized Queries with Different Variable Types from VBA?

In using SQL and parameterized queries from VBA, I am running into the following problem.
When I construct parameters, I can construct varchar and int parameters individually and use them correctly. However when I mix them, I get the following SQL error:
Operand type clash: text is incompatible with int
It seems SQL is smashing everything to text when I combine parameters of multiple types.
What do I have to do differently with my code (either VBA/SQL) to allow the third case to work (with parameters of varying types)?
Here is the VBA code:
Sub testAdodbParameters()
Dim Cn As ADODB.Connection
Dim Cm As ADODB.Command
Dim Pm As ADODB.Parameter
Dim Pm2 As ADODB.Parameter
Dim Rs As ADODB.Recordset
Set Cn = New ADODB.Connection
Cn.Open "validConnectionString;"
Set Cm = New ADODB.Command
On Error GoTo errHandler
With Cm
.ActiveConnection = Cn
.CommandType = adCmdText
Set Pm = .CreateParameter("TestInt", adInteger, adParamInput)
Pm.value = 1
Set Pm2 = .CreateParameter("TestVarChar", adVarChar, adParamInput, -1)
Pm2.value = "testhi"
'this works
If True Then
.CommandText = "INSERT INTO Test(TestInt) VALUES(?);"
.Parameters.Append Pm
End If
'this also works
If False Then
.Parameters.Append Pm2
.CommandText = "INSERT INTO Test(TestVarChar) VALUES(?);"
End If
'this fails with:
'Operand type clash: text is incompatible with int
If False Then
.Parameters.Append Pm
.Parameters.Append Pm2
.CommandText = "INSERT INTO Test(TestVarChar,TestInt) VALUES(?,?);"
End If
Set Rs = .Execute
End With
errHandler:
Debug.Print Err.Description
End Sub
Here is the SQL code to generate the table:
CREATE TABLE Test (
ID int IDENTITY(1,1) PRIMARY KEY,
TestVarChar varchar(50),
TestInt int
);
You are in VARCHAR, INT order in the query, you can try this:
.Parameters.Append Pm2
.Parameters.Append Pm
.CommandText = "INSERT INTO Test(TestVarChar,TestInt) VALUES(?,?);"
Does it work ?