Write SQL result/record directly to another database? - sql

I have the following script that reads records from a database successfully:
sDSN = MyDSN
sUsername = username
sPassword = password
sSQL ="Select TOP 1 * myTable"
sDSN = "DSN=" & sDSN & ";UID=" & sUsername & ";PWD=" & sPassword & ";"
Set sConnect = CreateObject("ADODB.Connection")
WScript.Echo "Opening connection to source..."
sConnect.Open sDSN
Set resultSet = sConnect.Execute(sSQL)
On Error Resume Next
resultSet.MoveFirst
Do While Not resultSet.eof
WScript.Echo resultSet("ID") & "," & resultSet("SomeColumn") & "," & resultSet("SomeOtherColumn")
resultSet.MoveNext
Loop
resultSet.Close
sConnect.Close
Set sConnect = Nothing
This works great and outputs something like the following:
1,value,value2
So what I want to do is write this back to another database. I realize I could manually write a query that specifies each column, but I'm wondering if there is some way to just insert the resultset() in one easy command.
Does anyone know if this is possible? It's CACHÉ since someone always asks :)

In VBScript, no there is no easy way. I am not sure what CACHE is or does, so that doesn't factor into my answer.
What you will need to do is build the text for the insert query on each loop of the result set.
dim InsertSQL = "insert into MyNewTable values (" & resultSet("ID") & "," & resultSet("SomeColumn") & ")"

If nobody has a better answer, this works fairly well and is reusable regardless of the table
tSQL = "INSERT INTO targetTable VALUES ("
For i = 0 To resultSet.fields.Count
tSQL = tSQL & resultSet(i)
if i <> resultSet.fields.Count Then
tSQL = tSQL & ","
end if
Next
tSQL = tSQL & ")"

Related

Access Run-Time error 2465. Can't find the field '1' referred to in your expression

I need help with this code.
Option Compare Database
Option Explicit
Private Sub BTNSEARCHOnetoOne_Click()
Dim SQL As String
SQL = "SELECT [00_SheetList-Revit-UNION].PACKAGE, [00_SheetList-Revit-UNION].DRAWING, [00_SheetList-Revit-UNION].DISCIPLINE, Hillsboro_OR_xlsx.FileName_Hillsboro_OR, Hillsboro_OR_xlsx.FilePath_Hillsboro_OR FROM Hillsboro_OR_xlsx, WHERE(([00_SheetList-Revit-UNION].PACKAGE) Like '" & Me.TXTKeywordsPackage & "') AND ((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
Me.SubONEtoONEInsideJoin.Form.RecordSource = SQL
Me.SubONEtoONEInsideJoin.Form.Requery
Me.SubONEtoONENullJoin.Form.Requery
End Sub
Private Sub Detail_Click()
End Sub
I narrowed it down to this part of the code.
"...((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
As I can take this part out and it works. Is this just syntax?
Currently, your SQL has a number of syntax issues:
Comma before WHERE clause;
Unclosed parentheses in last WHERE condition;
Unknown alias ([00_SheetList-Revit-UNION]) not referenced in FROM or JOIN clauses. Possibly you meant to cross join this source with Hillsboro_OR_xlsx.
See issues with current code with line breaks for illustration:
SQL = "SELECT [00_SheetList-Revit-UNION].PACKAGE," _
& " [00_SheetList-Revit-UNION].DRAWING," _
& " [00_SheetList-Revit-UNION].DISCIPLINE," _
& " Hillsboro_OR_xlsx.FileName_Hillsboro_OR, " _
& " Hillsboro_OR_xlsx.FilePath_Hillsboro_OR " _
& " FROM Hillsboro_OR_xlsx, " _
& " WHERE(([00_SheetList-Revit-UNION].PACKAGE) " _
& " Like '" & Me.TXTKeywordsPackage & "') " _
& " AND " _
& " ((Hillsboro_OR_xlsx.FileName_Hillsboro_OR) " _
& " Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')"
These issues can be mitigated with parameterized queries (an industry best practice when writing SQL in application code) which is supported in MS Access using QueryDef Parameters. Below are a few advantages and further below adjustment to your setup.
Saving a stored query instead of a VBA string query allows it is to be optimized by engine and the Access GUI will not allow query to be saved with syntax issues;
Abstract data from code, specifically VBA variables from SQL statement;
Readability and maintainability is enhanced.
SQL (with no VBA)
Save below as a stored Access query, using parameters and table aliases. Also, [00_SheetList-Revit-UNION] is cross joined (comma-separated in FROM clause) as assumed above.
PARAMETERS [PackageParam] Text;
SELECT o.PACKAGE, o.DRAWING, o.DISCIPLINE,
h.FileName_Hillsboro_OR, h.FilePath_Hillsboro_OR
FROM Hillsboro_OR_xlsx h, [00_SheetList-Revit-UNION] o
WHERE ((o.PACKAGE) Like [PackageParam])
AND ((h.FileName_Hillsboro_OR) Like '*' & o.DRAWING & '*');
VBA
Private Sub BTNSEARCHOnetoOne_Click()
Dim qDef As QueryDef
Dim rst As Recordset
' OPEN SAVED QUERY
Set qDef = CurrentDb.QueryDefs("mySavedQuery")
' BIND PARAMETERS
qDef![PackageParam] = "*" & Me.TXTKeywordsPackage & "*"
' BUILD RECORDSET FROM QUERYDEF AND SET TO SUBFORM
Set rst = qDef.OpenRecordset()
Me.SubONEtoONEInsideJoin.Form.Recordset = rst
Me.SubONEtoONENullJoin.Form.Requery
Set qDef = Nothing
End Sub
It looks like that you had something wrong here
you have written
Like '" & Me.TXTKeywordsPackage & "'
but it has to be like this
Like '*" & Me.TXTKeywordsPackage & "*'
you had this part wrong
check this below part
Like ('*" & ([00_SheetList-Revit-UNION].DRAWING) & "*')
Make sure that you are getting the value from textbox. It looks like you are calling table column.
Carefully count your parenthesis.
There should be an additional ) at the very end.

Uploading Volatile Table using VBA

I have a local table in an MS Access 2010 database. I would like to use ADODB to load the local table into a Teradata environment within my spool space using CREATE VOLATILE TABLE command
This should be achievable i think using arrays but i was wondering is there a better way (speedy too if possible) to batch load the records into the teradata environment for example
CREATE VOLATILE TABLE EXAMPLE AS (SELECT * FROM LOCAL TABLE)
WITH DATA PRIMARY INDEX(Set Index Keys)
ON COMMIT PRESERVE ROWS;
Thanks for your help
Just a quick update on this [24/01/2013]
I have managed to get the data from the access database, Load it into an Array, Create a Volatile table in my teradata warehouse using spool space and then attempt to load the array into the table
I am getting the error: TEMP_TABLE already exists. when trying to append the records to the table
I am almost there so any help would be greatly appreciated. Thank you again for your help
Public Function Open_Connection()
On Error GoTo ErrorHandler
' http://voices.yahoo.com/teradata-ms-excel-vba-2687156.html
' The connection is used to connect with the DBMS,
' The Recordset to surf the result of some SELECT queries
' The Command to send the sql requests to Teradata.
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim cmdSQLData As ADODB.Command
Set cmdSQLData = New ADODB.Command
Dim myArray() As Variant
' Open Connection With Teradata
cn.Open "Data Source=Database; " & _
"Database=Database; " & _
"Persist Security Info=True; " & _
"User ID=Me; " & _
"Password=FakePassword; " & _
"Session Mode=ANSI;"
' Which database it has to send the query
Set cmdSQLData.ActiveConnection = cn
' Query to create the violotile table in Teradata'
Query = "CREATE VOLATILE TABLE TEMP_TABLE ( " & _
"field1 VARCHAR (39)," & _
"field2 VARCHAR (44)," & _
"field3 DECIMAL (18, 3)," & _
"field4 CHAR (3))" & _
"ON COMMIT PRESERVE ROWS;"
' Query is assessed as Text
cmdSQLData.CommandText = Query
' Specifies which kind of command VBA has to execute
cmdSQLData.CommandType = adCmdText
' Remove Query Timeouts
cmdSQLData.CommandTimeout = 60
'VBA just run the query and send back the result
Set rs = cmdSQLData.Execute()
' Retrieve the sharepoint records into an Array
myArray = Retrieve_Sharepoint_Records
intNumberRows = UBound(myArray, 2) + 1 ' number of records/rows in the array
rowcounter = 0
' Append the Rows to the temp table
For rowcounter = 0 To intNumberRows - 1
' Debug.Print myArray(0, rowcounter) & " | " & myArray(1, rowcounter) & " | " & myArray(2, rowcounter) & " | " & myArray(3, rowcounter)
AppendQuery = "INSERT INTO TEMP_TABLE VALUES ('" & myArray(0, rowcounter) & "','" & myArray(1, rowcounter) & "'," & myArray(2, rowcounter) & ",'" & myArray(3, rowcounter) & "');"
cmdSQLData.CommandText = Query
cmdSQLData.CommandType = adCmdText
cmdSQLData.CommandTimeout = 60
Set rs = cmdSQLData.Execute()
Next
' Clean up
cn.Close
Set cn = Nothing
Set rs = Nothing
Set cmdSQLData = Nothing
ErrorHandler:
If (Len(Err.Description) > 0) Then
MsgBox (Err.Description)
End If
End Function
You may have better success using a Global Temporary Table as the object definition is stored within the DBC Data Dictionary on Teradata. The population of the table is session specific using the TEMPORARY space assigned to the user or the profile of the user.
Just to answer my own question, I should change the second code line of below
cmdSQLData.CommandText = Query
To
cmdSQLData.CommandText = AppendQuery
It then works perfectly albeit slowly
Again thank you all for your help

Access 2010 VBA Too few parameters: Expected 3

In VBA for Access 2010 and I am just trying to insert some data into a subform. I have a form, with 3 subforms on it. I have 3 unbound text boxes that the user will enter data, hit a command button, and then that data will instert into the subform I have on the layout. Here is my code:
Private Sub cmdAssign_Click()
CurrentDb.Execute " INSERT INTO Crew " _
& "(txtCrewName,txtKitNumber,txtActionDate) VALUES " _
& "(txtAssignCrew, txtAssignKit, txtAssignDate);"
End Sub
I know it has got to be something simple but I'm not really familiar with this. The txtCrewName, txtKitNumber, and txtActionDate are the empty values in the subform where I want data to go. And the txtAssignCrew, txtAssignKit, and txtAssignDate are the unbounds on the form, but outside of the subform 'Crew'. Any ideas? Thanks
EDIT: Figured it out. Thank you all for the help
So txtAssignCrew, txtAssignKit, and txtAssignDate are the names of controls on the form. The db engine doesn't know what they are, so assumes they must be parameters.
You could build those controls' values (instead of the controls' names) into your INSERT statement. But consider an actual parameter query instead, and execute it from a QueryDef object.
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strInsert As String
strInsert = "PARAMETERS crew_name Text(255), kit_num Long, action_date DateTime;" & vbCrLf & _
"INSERT INTO Crew (txtCrewName,txtKitNumber,txtActionDate)" & vbCrLf & _
"VALUES (crew_name, kit_num, action_date);"
Debug.Print "strInsert:" & vbCrLf & strInsert
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strInsert)
qdf.Parameters("crew_name") = Me.txtAssignCrew
qdf.Parameters("kit_num") = Me.txtAssignKit
qdf.Parameters("action_date") = Me.txtAssignDate
qdf.Execute dbFailOnError
Set qdf = Nothing
Set db = Nothing
Note, in the PARAMETERS clause I assumed text as the data type for txtCrewName, long integer for txtKitNumber, and Date/Time for txtActionDate. If all are text, adjust the PARAMETERS clause.
This should work, assuming txtAssignCrew, Kit, and Date are your unbound controls you want to insert. Realize that if there are single quotes or anything in those fields, it would cause the statement to fail, so you would need to escape them.
Private Sub cmdAssign_Click()
CurrentDb.Execute " INSERT INTO Crew " _
& "(txtCrewName,txtKitNumber,txtActionDate) VALUES " _
& "('" & me.txtAssignCrew & "', '" & me.txtAssignKit & "','" & me.txtAssignDate & ");"
End Sub
I may have botched a quote.
Corrected code:
CurrentDb.Execute " INSERT INTO Crew " _
& "(txtCrewName,txtKitNumber,txtActionDate) VALUES " _
& "('" & txtAssignCrew & "','" & txtAssignKit & "','" & txtAssignDate & ");"
Notes:
- You might need to change the format for the AssignDate parameter
- Column names in the database are usually not prefixed with txt
- You would be better off using parametized queries to avoid SQL injection attacks

Access VBA query to SQL Server

Hello experts I'm having trouble in my update query from SQL Server. Running first a select query then pass the result to currentdb.execute (to update the table of the access file currently using), using Access vba I'm not doing it right. I really hope you could help me. Maybe you guys know much better way to run my procedure:
connect to sql server 2008, run select query.
pass the result of select query to an access database execute command (or if you have a better idea) to update a table in the current access file that is using.
The error I'm getting to the code is Type mismatch and highlighting .OpenSchema.
These is part of the code that I made wrong (and I really have no idea how to do this).
dbObj.Execute ("UPDATE ACCESS.tbl_Name RIGHT JOIN " & _
conn.OpenSchema(adSchemaTables, Array(Empty, Empty, Empty, "SQLSVR.tbl_Name")) & _
" ON ACCESS.tbl_Name.FieldName_access = " & rst!FieldName_sqlsvr & _
" SET ACCESS.tbl_Name.FieldName_access = " & rst!FieldName_sqlsvr)
These is the whole code.
Option Compare Database
Sub LocalSQLServerConn_Test()
Dim dbOjb As DAO.Database
Dim strDBName As String
Dim strUserName As String
Dim strPassword As String
Set dbObj = CurrentDb()
Set conn = New adodb.Connection
Set rst = New adodb.Recordset
strDBName = "DataSet"
strConnectString = "Provider = SQLOLEDB.1; Integrated Security = SSPI; " & _
"Initial Catalog = " & strDBName & "; Persist Security Info = True; " & _
"Workstation ID = ABCDE12345;"
conn.ConnectionString = strConnectString
conn.Open
strSQL = "SELECT DISTINCT SQLSVR.tbl_Name.FieldName_sqlsvr FROM SQLSVR.tbl_Name"
rst.Open Source:=strSQL, ActiveConnection:=conn, _
CursorType:=adOpenDynamic, LockType:=adLockOptimistic
If rst.RecordCount = 0 Then
MsgBox "No records returned"
Else
rst.MoveFirst
Do While Not rst.EOF
dbObj.Execute ("UPDATE ACCESS.tbl_Name RIGHT JOIN " & _
conn.OpenSchema(adSchemaTables, Array(Empty, Empty, Empty, "SQLSVR.tbl_Name")) & _
" ON ACCESS.tbl_Name.FieldName_access = " & rst!FieldName_sqlsvr & _
" SET ACCESS.tbl_Name.FieldName_access = " & rst!FieldName_sqlsvr)
rst.MoveNext
Loop
End If
conn.Close
rst.Close
Set dbObj = Nothing
End Sub
You should add a linked table (or a pass-through query) to get the data from SQL Server, create an Update Query in your MDB, using a JOIN to update all rows at once (your can use the query designer for this part) and then execute that query using CurrentDb.Execute.

Updating Access Database from Excel Worksheet Data

I extract data from my Access database into an Excel worksheet using a macro. I first open a connection to the database, define my sql statement in a string var and then dump that data in a recordset:
Dim db As Database
Dim rs As RecordSet
Dim sql As String
Dim dbLocation As String
dbLocation = ThisWorkbook.Path & "\database\data.accdb"
Set db = OpenDatabase(dbLocation)
sql = "Select * FROM [Master Table]"
Set rs = db.OpenRecordSet(sql, dbOpenSnapshot)
If Not rs.EOF Then
Worksheets("Sheet1").Range("A1").CopyFromRecordset rs
End If
rs.Close
Set rs = Nothing
db.Close
Set db = Nothing
This works perfectly. I distribute this to some people and ask them to update fields. I then need to update the Access data with data that is passed back. The simple thing in terms of design is that the extracted excel data mirrors the access db in structure so the update query should be simple. Also there is a primary key, so I would just need to map on that field.
Any ideas how this can be done? Can I load the whole excel datasheet into a recordset and run some snazzy update query?
You need to loop over rows on sheet 1, and for each row make sql string that looks like:
"update [Master table] set
TableField1 = " & Range(Row, Col1).Value & ","
TableField2 = " & Range(Row, Col2).Value & ","
...
where IDTableField = " & Range(Row, IDColNum).Value
and then do
db.Execute thatString
PS: There are may be mistakes in my syntax. And you need to convert cell values to strings when making string.
An extension of shibormot's solution using DAO:
Set objConnection = CreateObject("DAO.DBEngine.36")
Set db = objConnection.OpenDatabase(strDBPath, blnExclusive, blnReadOnly, strPassword)
For Each row In Range("A1:C3").Cells
strSQL = "UPDATE table SET "
strSQL = strSQL & "Field1 = " & Chr(34) & row.Cells(1) & Chr(34) & ","
strSQL = strSQL & "Field2 = " & Chr(34) & row.Cells(2) & Chr(34) & ","
strSQL = strSQL & "Field3 = " & Chr(34) & row.Cells(3) & Chr(34)
Db.Execute
Next
Threw in the chr(34) for string data