i want to insert values into a table, with an INSERT INTO statement but i would like to use a different delimiter (not a comma) how do i do this?
i dont want to use a comma for the following reason:
the data is in this format:
|something|somethingelse|something3 ,moretextinsamefield|
field1 = "something"
field2 = "somethingelse"
field3 = "something3 ,something4"
Why don't you use the Split function which lets you specify a delimiter:
Dim aValues As Variant
aValues = Split("|something|somethingelse|something3 ,something4", "|")
ADDITION
Here is some sample code in VBA.
Public Sub AppendValues()
Const SOURCE_VALUES = "|something|somethingelse|something3 ,moretextinsamefield|"
Dim aValues As Variant
aValues = Split(SOURCE_VALUES, "|")
Dim oDB As DAO.Database
Dim oRS As DAO.Recordset
Set oDB = DBEngine.Workspaces(0).Databases(0)
Set oRS = oDB.OpenRecordset("Table1", dbOpenTable)
oRS.AddNew
oRS("Col1") = aValues(1)
oRS("Col2") = aValues(2)
oRS("Col3") = aValues(3)
oRS.Update
Set oRS = Nothing
Set oDB = Nothing
End Sub
Writing SQL to do this will get very complicated very quickly, with a bunch of nested Mid() and InStr() functions.
Instead, I'd do it with a function that uses Split().
Public Function SplitField(varInput As Variant, strDelimiter As String, lngItemRequested As Long) As Variant
Dim varTemp As Variant
Dim arrInput() As String
varTemp = varInput
If Left(varTemp, 1) = strDelimiter Then
varTemp = Mid(varTemp, 2)
End If
If right(varTemp, 1) = strDelimiter Then
varTemp = Left(varTemp, Len(varTemp) - 1)
End If
arrInput = Split(varTemp, strDelimiter)
If lngItemRequested - 1 <= UBound(arrInput()) Then
SplitField = arrInput(lngItemRequested - 1)
If SplitField = vbNullString Then
SplitField = Null
End If
Else
SplitField = Null
End If
End Function
Then in SQL, you'd call it thus:
INSERT INTO TargetTable( Field1, Field2, Field3, Field4 )
SELECT SourceTable.SourceField, SplitField([SourceField],"|",1),
SplitField([SourceField],"|",2),
SplitField([SourceField],"|",3),
SplitField([SourceField],"|",4)
FROM SourceTable
Note that the function I wrote can be used even when there is a variable number of subparts in the source field. That is, if some have 4 parts and some 2, it doesn't matter, as the function returns Null for the parts that aren't there.
Would it be easier to do a pre-insert operation and clean up the data? Replace the |'s with ,'s, and enclose all values in quotes (or something like that)?
If not, I think if you format the data in a text file, you can use Access to import text and specify that | is the delimiter, rather than ,.
Check out this article: Pipe Delimited File into access database
Try this code.
The approach is as given below.
Import the data from the text file to a temporary table ('Import')
Update existing records in the table ('Dest') by joining the imported
table and the existing table
Select the records from the 'Import' table which are not present
in the 'Dest' table
Insert these new records to the 'Dest'
You need to modify the queries as per
your table structure.
Dim conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=G:\VBNET\Access\bin\dest.mdb")
'Import data to a temporary table
Dim cmd As New OleDbCommand("SELECT * INTO [import] FROM [Text;FMT=Delimited;Database=G:\VBNET\Access\bin;Hdr=Yes].[Students.txt]", conn)
conn.Open()
cmd.ExecuteNonQuery()
'Update Existing records
Dim updateQuery As String = "UPDATE Dest INNER JOIN Import ON Dest.id = Import.F1 set Dest.Name = Import.F2"
Dim queryCmd As New OleDbCommand(updateQuery, conn)
queryCmd.ExecuteNonQuery()
Dim selectQuery = "select F1, F2, F3 from Import where F1 not in (select Id from Dest) "
queryCmd = New OleDbCommand(selectQuery, conn)
Dim dataReader As OleDbDataReader
dataReader = queryCmd.ExecuteReader()
Dim appendrecords As New ArrayList()
Dim insertQuery As String
While dataReader.Read()
Dim F1 As String = dataReader.GetString(0).ToString()
Dim F2 As String = dataReader.GetString(1).ToString()
Dim F3 As Integer = dataReader.GetInt32(2).ToString()
insertQuery = "insert into Dest values ('" & F1 & "', '" & F2 & "', " & F3 & ")"
appendrecords.Add(insertQuery)
End While
dataReader.Close()
Dim i As Integer
For i = 0 To appendrecords.Count - 1
Dim insertCmd As OleDbCommand = New OleDbCommand(appendrecords(i), conn)
insertCmd.ExecuteNonQuery()
Next
conn.Close()
If you prefer to do this with an INSERT statement, it's simple. Call the subroutine like this:
Call InsertValues("|something|somethingelse|something3 ,moretextinsamefield|")
Uncomment the Execute line to actually do the INSERT instead of just displaying the statement.
Public Sub InsertValues(ByVal pstrInput As String)
Dim i As Integer
Dim strSql As String
Dim strValList As String
Dim varValues As Variant
varValues = Split(pstrInput, "|")
'first and last array members are empty strings; skip them '
For i = 1 To 3
strValList = strValList & ", " & Chr(34) & varValues(i) & Chr(34)
Next i
'strip off leading comma and space '
strValList = Mid(strValList, 3)
strSql = "INSERT INTO YourTable (field1, field2, field3)" & _
vbNewLine & "Values (" & strValList & ");"
Debug.Print strSql
'CurrentDb.Execute strSql, dbFailOnError '
End Sub
Related
I am trying to write a vba code that will create a query in Access with a where condition based off of the value of a cell from another table. My issue is that when I am trying to pull a string from the varRecords(0,0) Variant it becomes a parameter for the new query and not a string. I tried using cstr() function but it was still becoming a parameter. If I use msgbox to test what is being created it appears as a string. I may have left some stuff out of the code but the basics are below.
Dim dbsEmails As DAO.Database
Dim rstEmails As DAO.Recordset
Dim varRecords As Variant
Dim RecordCounter As Long
Dim qdfTemp As QueryDef
Dim strSQL As String
Dim strSQL2 As String
Set dbsEmails = CurrentDb
strSQL = "Select Email, ID from tbl_Email"
Set rstEmails = dbsEmails.OpenRecordset(strSQL, dbOpenSnapshot)
rstEmails.MoveLast
RecordCounter = rstEmails.RecordCount
rstEmails.MoveFirst
varRecords = rstEmails.GetRows(RecordCounter)
strSQL2 = "Select ID, Stuff from tbl2 Where id =" & varRecords(0,0)
SetqdfTemp = CurrentDb.CreateQueryDef("Pending Report", strSQL2)
End Function
Try making it a string:
strSQL2 = "Select ID, Stuff from tbl2 Where id = '" & varRecords(0,0) & "'"
This question already has an answer here:
DataTable.Load() Throws Error: Undefined function 'CountWeekDays' in expression
(1 answer)
Closed 6 years ago.
i used this funtion to concatenate datarows..
Public Function GetList(SQL As String _
, Optional ColumnDelimeter As String = ", " _
, Optional RowDelimeter As String = vbCrLf) As String
'PURPOSE: to return a combined string from the passed query
'ARGS:
' 1. SQL is a valid Select statement
' 2. ColumnDelimiter is the character(s) that separate each column
' 3. RowDelimiter is the character(s) that separate each row
'RETURN VAL: Concatenated list
'DESIGN NOTES:
'EXAMPLE CALL: =GetList("Select Col1,Col2 From Table1 Where Table1.Key = " & OuterTable.Key)
Const PROCNAME = "GetList"
Const adClipString = 2
Dim oConn As ADODB.Connection
Dim oRS As ADODB.Recordset
Dim sResult As String
On Error GoTo ProcErr
Set oConn = CurrentProject.Connection
Set oRS = oConn.Execute(SQL)
sResult = oRS.GetString(adClipString, -1, ColumnDelimeter, RowDelimeter)
If Right(sResult, Len(RowDelimeter)) = RowDelimeter Then
sResult = Mid$(sResult, 1, Len(sResult) - Len(RowDelimeter))
End If
GetList = sResult
oRS.Close
oConn.Close
CleanUp:
Set oRS = Nothing
Set oConn = Nothing
Exit Function
ProcErr:
' insert error handler
Resume CleanUp
End Function
the query i used is
SELECT OB.Operation_Type, OB.Machine_Type, OB.Attatchment, GetList("Select Operation_Name From OB As T1 Where T1.Operation_Type = """ & [ob].[Operation_Type] & """ and T1.Machine_Type = """ & [ob].[Machine_Type] & """ and T1.Attatchment = """ & [ob].[Attatchment] & """ ",""," + ") AS Expr1
FROM ob
GROUP BY ob.Operation_Type, Machine_Type, Attatchment;
Now i need to call this query from vb.net
i tried as follows::
myConnection.Open()
Dim db As New OleDb.OleDbDataAdapter
Dim cn As New OleDb.OleDbConnection
Dim dt As New DataTable
Dim ds As New DataSet
Dim cmd As New OleDbCommand("Query", myConnection)
Try
cmd.Connection = myConnection
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "Query"
db.SelectCommand = cmd
db.Fill(dt)
Me.DataGridView1.DataSource = dt
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
myConnection.Close()
this is giving error as follows
"Undefined function 'GetList' in expression."
Please Help
Thank You!
The error message is clear. You send the SQL string to Access which then looks for the function GetList which it, of course, cannot find.
You will have to rethink your concept.
I have 60 MS Access files with the same database structure. I want to take data from two tables which are in relation from each database to make one single database with all of the records from those 60 files. Is there any easy way to merge all those MS Access files?
If I understand you correctly, you have identical tables spread across 60 database files, and you are looking at a way of automating their aggregation.
There's a few different ways you can do this. It'll probably depend on your circumstances. I've demonstrated two different approaches.
The first method is straightforward. It simply builds a static query, substituting the database name into each query. If your specifics are simplistic - then this should do the trick.
The second method uses DAO to open each table in each database and write the data to the current database. This method is beneficial if you have one-off exceptions and need to add some intelligence.
Public Sub SimpleCombine()
Dim DBFileList As Collection
Dim DBPath As String
Dim ForeignTableName As String
Dim LocalTableName As String
Dim dbfile As Variant
' Configure
Set DBFileList = New Collection
DBFileList.Add "Test1.accdb"
DBFileList.Add "Test2.accdb"
DBPath = CurrentProject.Path ' (No Trailing Backslash)
ForeignTableName = "Fruit"
LocalTableName = "Fruit"
For Each dbfile In DBFileList
querystr = "INSERT INTO Fruit (FruitName, FruitValue) " & _
"SELECT FruitName, FruitValue " & _
"FROM Fruit IN '" & DBPath & "\" & dbfile & "'"
Debug.Print "Transferring Data From " & dbfile
CurrentDb.Execute querystr
DoEvents
Next
End Sub
Example #2
Public Sub DAOCombine()
Dim DBFileList As Collection
Dim DBPath As String
Dim ForeignTableName As String
Dim LocalTableName As String
Dim db As DAO.Database
Dim rst, drst As DAO.Recordset
Dim fld As DAO.Field
' Configure
Set DBFileList = New Collection
DBFileList.Add "Test1.accdb"
DBFileList.Add "Test2.accdb"
DBPath = CurrentProject.Path ' (No Trailing Backslash)
ForeignTableName = "Fruit"
LocalTableName = "Fruit"
Set drst = CurrentDb.OpenRecordset(LocalTableName)
For Each dbfile In DBFileList
Debug.Print "Transferring Data From " & dbfile
Set db = DBEngine.Workspaces(0).OpenDatabase(DBPath & "\" & dbfile)
Set rst = db.OpenRecordset(ForeignTableName)
Do Until rst.EOF
drst.AddNew
For Each fld In rst.Fields
If (fld.Attributes And dbAutoIncrField) = dbAutoIncrField Then
' We have an autonumber field - lets skip
Else
drst.Fields(fld.Name).Value = fld.Value
End If
Next
drst.Update
rst.MoveNext
Loop
rst.Close
DoEvents
Next
drst.Close
Set rst = Nothing
Set drst = Nothing
End Sub
You'll need to tailor the code to your specific circumstances - but it should do the trick.
If the datastructure is the same you can use a JOIN
Query.
SELECT PORDER_ARV.*
FROM PORDER_ARV
UNION
SELECT PORDER_RAN.*
FROM PORDER_RAN
UNION
SELECT PORDER_HOL.*
FROM PORDER_HOL
UNION SELECT PORDER_HIN.*
FROM PORDER_HIN
ORDER BY PURCHASE_CODE;
When you use Union All ,you will also get duplicates, you can write vba code to auto construct this sql string with your 60 table names. I don't no if the union function works with 60 tables?
I have this code now. But it fails at three steps. Can you help me figure this out??
I have listed the three points where it fails.
Also please validate for me If I'm doing it right?
Retrieve the string from the tb_metatags textbox
Dim s As String
s = Me!tb_metaatags
parse the string into substrings by looking for the commasDim arrLines() As String
Dim arrLines() As String
arrLines = Split(s, ",")
For each substring, check if the substring is in the MetaSearchTags table
Dim itm As Variant
For Each itm In arrLines
Dim strsql As String
Dim numrows As Integer
strsql = "SELECT COUNT(*) FROM MetaSearchTags WHERE SearchTag = " & itm & ""
Dim objcmd As New OleDbCommand(strsql, conn) "I get an error here
numrows = objcmd.ExecuteScalar
If numrows > 0 Then
MsgBox("Record Exists", vbInformation, "Add") "I get an error here
Else
Dim myadapter1 As New OleDbDataAdapter("INSERT INTO MetaSearchTags ( SearchTag) "VALUES ('" & itm & "')", conn) "I get an error here
Dim mytable1 As New DataTable
myadapter1.Fill (mytable1)
End If
if it is not already in the MetaSearchTags table, then add it to the table
get the primary key (ID) for the substring from the MetaSearchTags table
Add an row in the MetaSearchTagAssignments table for this search tag
using the projectID, and the substring ID from the MetaSearchTags table
Repeat this process for each substring entered in the field
OleDbCommand.ExecuteScalar returns
The first column of the first row in the result set, or a null
reference if the result set is empty.
You need to handle this null reference (in VB.NET this equates to Nothing) when no records are returned.
One way to do this is:
Dim numrows as String = String.Empty
numrows = objcmd.ExecuteScalar()
If numrows Is Nothing Then
'Do something with the error condition
Else
'Do something with numrows which contains a valid result.
End If
(I would rename numrows)
You are also attempting to insert a record into the table even though no results are returned. This wouldn't be an error, but you have indicated (although it is a little difficult to interpret) that SearchTag is a primary key, in which case it will be an error to attempt to insert a duplicate.
And, as mentioned, you need to correct the quotes and apostrophes for your INSERT statement.
You need to put single quotes around strings in SQL statements:
strsql = "SELECT COUNT(*) FROM MetaSearchTags WHERE SearchTag = " & itm & ""
Should be:
strsql = "SELECT COUNT(*) FROM MetaSearchTags WHERE SearchTag = '" & itm & "'"
I am trying to update an Oracle Database record and i keep getting this error:
ORA-01704: string literal too long 5
I looked up that error and it seems that i have a limit of 4000 charters since i am using Oracle 10g. However, the prgblem is that its the same exact data i am putting back into that record so that is why i am unsure as to why its giving me that error for the same amount of data i took out of it.
Here is my update code:
Dim myCommand As New OracleCommand()
Dim ra As Integer
Try
myCommand = New OracleCommand("Update CSR.CSR_EAI_SOURCE Set STATUS_CODE = 'Blah', COMPLETE_DATE = '', DATA = '" & theData & "' WHERE EID = '81062144'", OracleConnection)
ra = myCommand.ExecuteNonQuery()
OracleConnection.Close()
Catch
MsgBox("ERROR" & Err.Description & " " & Err.Number)
End Try
I'm not sure if there is anything special you have to do in order to update a clob or not.
I extract the clob like so:
Dim blob As OracleClob = dr.GetOracleClob(9)
Dim theData As String = ""
theData = blob.Value
And it works just fine extracting but just not putting it back in.
Any help would be great!
David
UPDATE CODE
Dim OracleCommand As New OracleCommand()
Dim myCommand As New OracleCommand()
Dim ra As Integer
While dr.Read()
Dim blob As OracleClob = dr.GetOracleClob(9)
Dim theData As String = ""
theData = blob.Value
theData = Replace(theData, "…", " ")
Try
Dim strSQL As String
isConnected2 = connectToOracleDB2()
OracleConnection.Close()
If isConnected2 = False Then
MsgBox("ERRORConn: " & Err.Description & " " & Err.Number)
Else
myCommand.Connection = OracleConnection2
strSQL = "Update CSR.CSR_EAI_SOURCE Set STATUS_CODE = 'ERROR', COMPLETE_DATE = '', DATA = :1 WHERE EID = '" & theEID & "'"
myCommand.CommandText = strSQL
Dim param As OracleParameter = myCommand.Parameters.Add("", OracleDbType.Clob)
param.Direction = ParameterDirection.Input
param.Value = theData
Application.DoEvents()
ra = myCommand.ExecuteNonQuery()
Application.DoEvents()
OracleConnection2.Close()
Application.DoEvents()
End If
Catch
MsgBox("ERROR: " & Err.Description & " " & Err.Number)
OracleConnection2.Close()
End Try
End While
dr.Close()
OracleConnection.Close()
Do not hardcode the value into your SQL query. Instead wrap it in a parameter. Like this:
Dim strSQL As String
strSQL = "Update CSR.CSR_EAI_SOURCE Set STATUS_CODE = 'Blah', COMPLETE_DATE = '', DATA = :1 WHERE EID = '81062144'"
myCommand.CommandText=strSQL
And then:
Dim param As OracleParameter=myCommand.Parameters.Add("",OracleDbType.Clob)
param.Direction=ParameterDirection.Input
param.Value=blob.Value
You can (and should) of course add all other variables (status code, complete date, eid) of your query as parameters, too, instead of hard-coding them into your SQL.
Varchar2 in sql has a limitations of 4000 characters. This limitation does not apply to the data stored in a varchar column. You need to convert this to pl\sql or specify some other column type. ( I am not a php expert. So I cannot provide any sample, just the reason for your error).
Essentially you need to specify the data type as clob while executing the bind query. Otherwise it will default to varchar2 and the above limitation will apply.