Importing a text file into Postgres using ODBC - vb.net

I am trying to directly import a text file into Postgres, but using ODBC. I realize that this is a bit of an odd thing to do, but ODBC does a good job of fixing/ignoring errors in the text files and Postgres' Copy command is very, very picky. I use Copy when I can and ODBC where I can't.
I am currently doing this in two steps. ODBC Import to Access and then from Access to Postgres but I recently learned over on MSDN I may be able to do this in one step but am having trouble with the SQL.
Here is the code I am using:
Dim TextConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=c:\PathToTextFile;Extended Properties=""Text;HDR=No""")
Dim TextCommand As System.Data.OleDb.OleDbCommand
TextCommand = New System.Data.OleDb.OleDbCommand("SELECT * INTO [ODBC;Driver={PostgreSQL};" & _
" Server=server;Database=database;Uid=UserName;Pwd=Password;].[TableName] FROM [textfile.txt]", TextConnection)
TextCommand.ExecuteNonQuery()
I am getting this error: Query input must contain at least one table or query.
I am not where to go from here in debugging this. It also just might now be possible and that would be good to know.

Related

Connect to SQL via ODBC using a .bat

I am currently performing a SQL query using Oracle SQL Developer and pasting in a standard query (same SELECT every time), then exporting to a csv file. I would like to execute the query via a batch file and place the output in a specified folder. I already use many batch files on this machine and would like to make this query part of a routine.
My machine has an existing ODBC connection to "WHPROD", but I do not know how to use it. Is there a way to connect to WHPROD from a batch file?
This is hardly possible in batch script directly without going overcomplicated
However it is simple to do it with VBscript, and since you can call your VBscript from a batch script, the result will be exactly what you want.
Here's an example of how to connect to Oracle and retrieve the results of a SELECT from VBS : (source)
Dim strCon
strCon = “Driver={Microsoft ODBC for Oracle}; ” & _
“CONNECTSTRING=(DESCRIPTION=” & _
“(ADDRESS=(PROTOCOL=TCP)” & _
“(HOST=Server_Name)(PORT=1521))” & _
“(CONNECT_DATA=(SERVICE_NAME=DB_Name))); uid=system;pwd=system;”
Dim oCon: Set oCon = WScript.CreateObject(“ADODB.Connection”)
Dim oRs: Set oRs = WScript.CreateObject(“ADODB.Recordset”)
oCon.Open strCon
Set oRs = oCon.Execute(“SELECT name from v$database”)
While Not oRs.EOF
WScript.Echo oRs.Fields(0).Value
oRs.MoveNext
Wend
oCon.Close
Set oRs = Nothing
Set oCon = Nothing
And here's how to call your VBS from the batch script :
#echo off
start "C:\\yourbatchfolder\\yourscript.vbs"
I wrote an in-depth batch script once that builds a MSSQL database. There are lots of great hints in that script that may help you get going.
The script is not specifically using ODBC but I do believe SQLCMD args can be changed to use a ODBC defined connection? That may work for you; and not just on MSSQL server.

Excel: Saving query results directly to CSV file

I have a dataset in Excel, of which I have to save an assorted part to a new csv file. I have used SQL to select the part required to be saved. I was hoping somebody would guide me about saving this selection to csv using SQL.
SQL gives me a recordset but I would like to loop through it only as a last resort. I am hoping there is a better approach that directly saves the entire result from within the query itself if possible.
Something like the solution by Remou on Want VBA in excel to read very large CSV and create output file of a small subset of the CSV is what I'm looking for. But unfortunately I can't get that to work.
Assuming you are in Excel VBA, has an ADODB opened with a Recordset object connected to a database and you want to save the content into a CSV (from within the Excel VBA).
The easiest is actually still by looping through the records in the recordset.
However, since you already rule that out (for whatever reasons), the next option would be to use the Recordset.Save <StreamObject> method. Create a System.IO.Streamwriter object to pass to the Recordset.Save.
OR, another way if you are using Jet SQL is:
conDB.Execute "SELECT * INTO [Text;Database=" _
& vsCSVFolder _
& ";HDR=No;FMT=Delimited].[" _
& vsCSVFileame _
& "] FROM Attendance", _
DBExport, _
adCmdText Or adExecuteNoRecords
Hope this helps.

Problem reading dBase DBF with non-English characters

I have a tool which reads dBase files and uploads the contents to SQL Server, part of a system to import shapefiles. It works but now we have a requirement to import files that include non-English characters (Norwegian in this case, could be other languages later) and they're being corrupted.
The dBase files are being read using an OleDbDataAdapter. Stepping through the code I can see that the text is wrong as it is read in. I'm assuming it's something to do with code pages or Unicode but I have no idea how to fix it.
A dBase Reader application tells me the DBFs are in code page 1252 - I don't know if this is correct. My upload tool runs on Win7 with English (UK) regional settings.
Examples:
ÅSGARD in DBF becomes +SGARD in VB.Net & SQL Server.
RINGHORNE ØST in DBF becomes RINGHORNE ÏST in VB.Net & SQL Server.
The code that reads the DBF:
dbfConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath & ";Extended Properties=dBASE IV"
Cnn.ConnectionString = dbfConnectionString
Cnn.Open()
strSQL = "SELECT * FROM [" & strDBF & "]"
DA = New OleDb.OleDbDataAdapter(strSQL, Cnn)
DS = New DataSet
DA.Fill(DS)
If DS.Tables(0).Rows.Count > 0 Then
dtDBF = DS.Tables(0)
Else
dtDBF = Nothing
End If
Data is read like: Name = dtDBF.Rows(index)("NAME_1")
Is there a way to tell OleDbDataAdapter what code page to use or a better way to read dBase files from VB.Net?
Try adding this to your DSN:
CollatingSequence=Norwegian-Danish
You might also be able to use:
CollatingSequence=International
Check whether the shapefile contains codepage information. There are two places to look
Look in the language driver ID (LDID), which is found in the header of the shapefile’s DBF table (in the 29th byte).
Look for an associated separate file with extension .cpg.
If the code page is not specified in those locations, it defaults to the codepage on the PC that generated the shapefile. You will just have to know that :(
I've never used it, but maybe Shape2SQL takes care of this for you? Or shp2text? I believe the PostGIS shapefile loader handles code pages: maybe you could import into PostGIS and then export in another format??
Old question, but this may answer it for future readers...
You might try adding a property setting in your connection string:
Locale Identifier=1044
This property (and a list of values including this one) is documented for ADO in conjunction with Jet 4.0's OLDB Provider but I have no reason to believe it isn't also supported by ADO.Net. This value (1044) is Norwegian/Danish.
Untested, but something else to try.

sqlite in vb.net, can't find table even though it exists

I'm using the following code (System.Data.SQLite within VB.net):
Dim SQLconnect As New SQLite.SQLiteConnection()
Dim SQLcommand As SQLiteCommand
SQLconnect.ConnectionString = "Data Source=vault.db;"
SQLconnect.Open()
SQLcommand = SQLconnect.CreateCommand
SQLcommand.CommandText = "INSERT INTO entries VALUES ('" & appinput.Text & "','" & userinput.Text & "','" & passinput.Text & "')"
SQLcommand.ExecuteNonQuery()
SQLcommand.Dispose()
SQLconnect.Close()
Me.Hide()
I get an error back that says it can't find the table "entries"
I know the table exists because I can write to it via the command line through sqlite and through Autoit and can see it and edit it in the SQLite browser when I open the database. I don't understand why VB can't see it (I know it sees and opens the database file just fine). Any ideas?
Most likely your problem is with relative paths (directories).
sqlite will create a database file if it does not exist so you will never get a "db file not found message". The first indication of an incorrect path is "table missing".
My personal experience is that although it goes against my programmers instinct is to alway use an absolute (fully qualified) path/file name for an sqlite database.
If you put in the full file location like "/var/myapp/vault.db" you should be OK.
If this is likly to move around store pick up the file name from a properties/config file -- 'config file not found' is much easier to deal with than "table not found".
Argh! There are 3 big issues in that code. Please update it like this to fix two of them:
Using cn As New SQLite.SQLiteConnection("Data Source=vault.db;"), _
cmd As New SQLiteCommand("INSERT INTO entries VALUES (#AppInput, #UserInput, #PassInput)", cn)
cmd.Parameters.AddWithValue("#AppInput", appinput.Text);
cmd.Parameters.AddWithValue("#UserInput", userinput.Text);
cmd.Parameters.AddWithValue("#PassInput", passinput.Text);
cn.Open()
cmd.ExecuteNonQuery()
End Using
This will prevent sql injection by parameterizing your query instead of substituting values directly and prevent db locking issues by making sure your connection is disposed properly, even if an exception is thrown.
The third problem is that you should NEVER store plain-text passwords in your database (or anywhere else for that matter). Go read up on how to hash values in .Net and hash and salt your password before storing or comparing it.
Once you've done that re-test your code to see if you still get the same errors reported as before. We need to make sure this didn't solve the problem or introduce something new. Then we can start addressing the missing table issue, perhaps by checking your connection string.
I had a similar error with SQLite (via .Net) refusing to believe the table existed, even though direct access confirmed it was there. The error could be produced only on one individual machine and not others. Hard coding the path didn't seem to fix the problem. The fix was either to run the program as Administrator or change the DB file to be available to Everyone. Apparently the .Net assembly raises a missing table error when the actual problem is access restrictions.

How can I connect to Lotus thru ODBC using VBA?

I'm interested in setting up an Access db to run a report automatically. To save myself the trouble of going to each client computer and setting up the appropriate DSNs, I'd like to set up the ODBC connections in the VB script itself if possible.
I've googled and checked this site and found some good starter code, but not enough to make all the error messages go away. Can someone complete the code below?
Sub SetupODBC(Str_Server as string, Str_Db as string)
'Str_Server=Name of Server
'Str_db=Name of Database
Dim C as ADODB.Connection
Set C = new ADODB.Connection
C.ConnectionString = ??
C.Open
Debug.print C.State
Exit Sub
Welcome to the board. ConnectionStrings is indeed your friend, but the issue you are having is that you don't have the driver:) Lotus Notes is not a relational database it is a document oriented database. Historically there has not been a way to Access it like it is a relational database for that reason. However IBM eventually got around to writing a sort of translator in the form of NotesSQL. If you follow the link and get the driver you should be able to use ODBC. It is worth noting that Notes exposes itself to COM. So if push comes to shove you can automate the client.
This site is your friend: http://www.connectionstrings.com/access
I didn't follow your question correctly at first. I see you want to create a link from Access to Lotus to report on Lotus Notes data. Well there are a few ways to do so.
I frequently use a method of exposing Lotus Notes data as XML, then accessing that XML from the remote system. You can easily create a Notes Page with the XML start tag, root element, and then insert an embedded view in between the root element. That embedded view then needs to display as HTML and contain columns that resolve to xml tags. For instance, each row of the view would look similar to this:
<Person><FirstName>Ken</FirstName><LastName>Pespisa</LastName></Person>
and your column formulas would be:
"<Person><FirstName>" + FirstName + "</FirstName>"
for the first name column, and for the last name column it would be this:
"<LastName> + LastName + </LastName></Person>"
Note that this assumes that your Notes server has the HTTP service turned on and you can reach the database via a browser.
However as mentioned by other answers, you can use other methods such as NotesSQL and COM. It sounds like you are putting this solution on many workstations, though, and NotesSQL would require you to install the driver on each workstation. The COM method would work without requiring any extra work at the users' desks so I'd favor that solution in this case.
Looks like a great site for my needs, even if it hasn't been updated in a year. But still no cigar. Now, I'm getting "Data source name not found and default driver not specified"
(Obviously, ServerNameGoesHere and DatabaseNameGoesHere are subsitutions)
Sub dbX()
Dim C As adodb.Connection
Set C = New adodb.Connection
C.Open _
"Driver={Lotus NotesSQL 3.01 (32-bit) ODBC DRIVER (*.nsf)};" & _
" Server=ServerNameGoesHere;" & _
" Database=DatabaseNameGoesHere.nsf;"
C.Close
End Sub