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.
Related
I am just starting to move our Access DB to SQL Server and am having trouble.
I have a stored procedure that successfully returns rows to an ado recordset.
When I try to bind the rs containing the results of the stored procedure to the Access form, Access crashes without displaying any error messages. I'm on O365 32b and SQL Server 2019.
Here's the code:
Dim sSQL As String, rs As ADODB.Recordset
1 sSQL = "Exec usp_TaskStatusWidget " & Me.Tag & ",0"
2 ADOConn.ConnectionString = conADO
4 ADOConn.Open
6 Set rs = New ADODB.Recordset
7 rs.CursorLocation = adUseClient
8 rs.Open sSQL, ADOConn
10 Set Me.Recordset = rs ' Access crashes here
. . .
Any help would be greatly appreciated!
tia.
SR
Ok, are you previous using ADO, or are you just introducing this?
In most cases, you are better off to just use a view. (replace the access query with a linked view), and then continue useing client side where clauses or filters (access will ONLY pull down the rows you request). So linked views are often a better choice and much less work (in fact, even existing filter for a open report etc. will work and only critera matching the were clause records are pulled.
And in most cases, i don't introduce ADO.
So for a PT query, I often do this:
dim rs as DAO.RecordSet
with CurrentDb.queryDefs("qryPt")
.SQL = "Exec usp_TaskStatusWidget " & Me.Tag & ",0"
set rs = .OpenRecordSet
end with
So, above assumes you have a pt query called qryPt. This also means that you never deal with or worry about connection strings in code. The pt query has the connection. (and your re-link code now can re-link tables and pt queries).
I ONLY suggest the above as a FYI in case that you introducing ADO for calling store procedures, and the rest of the application was previous DAO. If the application was previous DAO, then leave it alone, and use above approach for your PT queries - even code that needs to call store procedures.
Access tends to try and parse the query text to get filters/sorts/etc to work, and if it isn't a plain syntax error but isn't Access SQL either, strange things tend to happen, mostly crashes.
Try adding a comment up front to make sure Access knows not to parse:
sSQL = "-- Access no parse pls" & vbCrLf & "Exec usp_TaskStatusWidget " & Me.Tag & ",0"
The content of the comment is not relevant, of course, its purpose is to immediately cause a syntax error when Access tries to parse it as Access SQL (which doesn't have comments)
I am familiar with SQL (especially postgres) and VBA, but on the Apache spark side, I am a total newbie, but it seems to run and return queries results much faster than using SQL?
As of now in my daily work, I connect my Excel VBA with Postgresql through OLEDB (others ppl use ODBC and etc.), so whenever I need to retrieve something from DB, I can easily do so by set a connection and write a SQL string in VBA, and then dump the output in the desired sheets and cells. But the drawback there is the speed, as my data grows larger and larger, when I need to run complicated SQL queries for complicated calculations or relations, it took a long long wait to get the results.
So other than upgrade our server which host the DB, I heard Spark/Hadoop is the solution for speeding up the task?
Typically when I need to do the VBA-postgres interaction, I do something like the following:
Public Sub refresh_cf()
Dim dataConn As New ADODB.Connection
Dim strSQL As String
Dim strCON As String
Dim strCmd As New ADODB.Command
Dim loadTable As QueryTable
strCON = "Server=server IP;" & _
"DSN=PostgreSQL35W;" & _
"UID=USERNAME;" & _
"PWD=PASSWORD;" & _
"Database=DBNAME;" & _
"Port=5432;" & _
"CommandTimeout=12"
dataConn.ConnectionString = strCON
dataConn.Open
strSQL = "SELECT * FROM TABLE WHERE...."
strCmd.ActiveConnection = dataConn
strCmd.CommandType = adCmdText
strCmd.CommandText = strSQL
strCmd.CommandTimeout = 0
Set loadTable = Sheet2.QueryTables.Add(Connection:=strCmd.Execute,
Destination:=Sheet2.Range("A4"))
With loadTable
.BackgroundQuery = False
.AdjustColumnWidth = False
.refresh
End With
End Sub
I am wondering if we can achieve the same to connect with Apache Spark or Hadoop and return query results by this way??
Say each of the databases we are processing is fairly huge, billions of rows (and countless cells per row), and if I perform some complex relational calculations within this DB, currently the postgres on our server may take hours if not days to complete the task (even the returned results might not be that big, i.e. does not exceed the 1.6 million rows limit of per excel sheet), is it worthy to utilize Hadoop or Spark via VBA if possible?
I know we can do this in Python for sure, something like:
Python
from pyspark.sql import HiveContext, Row
#or
from pyspark.sql import SQLContext, Row
sc = SparkContext(...)
hiveCtx = HiveContext(sc)
#Then we can run query
hiveCtx.sql("""SELECT * FROM TABLE WHERE....""")
Moreover, I find a link which introduced the ODBC connection to Hadoop, but can someone share your way if you are doing so, and provide some basic example code to clarify the process? Thanks.
I don't have Hadoop installed on my personal laptop, so I can't test this process, but I think it should be essentially like this.
You can see all details here.
https://learn.microsoft.com/en-us/azure/hdinsight/hadoop/apache-hadoop-connect-excel-hive-odbc-driver
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.
I need you help to get the syntax for assigning the server, port and database name using parameters.
the script works perfectly fine if I pass the variable in the command explicitly.
Dim myConn1 As Odbc.OdbcConnection = New Odbc.OdbcConnection("Driver=Adaptive Server Enterprise;uid=XXX;server=& SRVR &;port=& PRT &;database=& dbname &;pwd=XXX")
Please advise me where am I going wrong.request for Your prompt assistance.
Thanks
Mayur
You're not actually concatenating any strings. How many double quotes are there in this:
"Driver=Adaptive Server Enterprise;uid=XXX;server=& SRVR &;port=& PRT &;database=& dbname &;pwd=XXX"
There are exactly two, which means that that whole thing is one string. If you want to join multiple strings then there have to actually be multiple strings:
"Driver=Adaptive Server Enterprise;uid=XXX;server=" & SRVR & ";port=" & PRT & ";database=" & dbname & ";pwd=XXX"
You can avoid silly issues like this by not using string concatenation in the first place. You could use String.Format or, in VB 2015, string interpolation to make things clearer or you could do what you're supposed to do when building a connection string from parts and use a connection string builder. As you're building an ODBC connection string, you would use the OdbcConnectionStringBuilder class:
Dim builder As New OdbcConnectionStringBuilder("Driver=Adaptive Server Enterprise;uid=XXX;pwd=XXX")
builder("server") = server
builder("port") = port
builder("database") = database
Using connection As New OdbcConnection(builder.ConnectionString)
'...
End Using
I am updating someone elses old code from a VB6 windows application to a VB.Net web application. I understand the old code, but I am not sure how I would translate it to .Net recordsets.
myStoredProcedure = "sp_WritevPayrollCurrent"
myCurrentPast = "'N'"
myStoredProcedure = "sp_ObtainSubClassID"
myClassName = "Payroll Major"
mySubClassName = "New Hire"
Set rs = TgetReadResultsetWithParms(myClassName, mySubClassName, (myStoredProcedure))
Also, I am not sure what will happen with "myStoredProcedure" being declared twice or could that be an error?
The TgetReadResultsetWithParms function is as follows (some Cases redacted to free up space):
Dim en As rdoEnvironment
Dim cn As rdoConnection
Dim rq As rdoQuery
rdoDefaultCursorDriver = rdUseServer
'open a connection to the tstdbexecutive database using DSNless connections
Set en = rdoEnvironments(0)
Set cn = connectionstring stuff here
Select Case myStoredProcedure
'create reusable rdoQuery and Call SQL server stored procedure.
Case "sp_ObtainClassID"
Set rq = cn.CreateQuery("", "{call " & cstDatabaseName & ".dbo.sp_ObtainClassID(?)}")
Case Else
Set rq = cn.CreateQuery("", "{call " & cstDatabaseName & ".dbo." & myStoredProcedure & "(?)}")
End Select
'set the input argument value for the store procedure.
rq(0) = myParm1
'open the Resultset and pass it back to calling procedure
Set TgetReadResultsetWithParm = rq.OpenResultset(rdOpenKeyset, rdConcurReadOnly)
The VB6 code is using Remote Data Objects. I think you will have to read the documentation to understand what the VB6 is doing, and then rewrite in VB.Net using ADO.Net to achieve the same functionality. AFAIK there is no handy cheat-sheet which shows how RDO compares with ADO.Net, unfortunately. There are some for ADO-ADO.Net.
Alternatively you could add a reference to Remote Data Objects in your .Net project - you can use COM objects in .Net - and then use the same code. If there is a large amount of the old code, this could be a pragmatic way to make the task more manageable, although it makes the code harder to understand for other programmers who would probably be used to ADO.Net. It's better to rewrite if you can afford to.