I have a current vbscript that runs a simple sql statement and passes this to a crystal report to run against a sybase database - like below
SybaseRecordSet.Open "SELECT * FROM v2Region where code IN ('BTN', 'MAN', 'IRE', 'DUB')", SybaseConnection, adOpenStatic, adLockOptimistic
I would like to run a more complex sql statement and have tried various ways to add this into the sql script without success
Is there a way for the command below to open an external sql txt file into a variable and then open like below
Function do_something
Dim fso
Set file = fso.OpenTextFile("D:\ideal v2.5\Amalgamated_Overdue_Report.sql", 1)
sql_content = file.ReadAll
SybaseRecordSet.Open sql_content, SybaseConnection, adOpenStatic, adLockOptimistic
currently this is giving
Error - Object required: 'fso'
code - 800A01A8
Related
Note that both databases are MS SQL Server.
The SELECT works fine and the code doesn't break until it gets to ADODB.Recordset.Update. The SQL account has all of the necessary permissions. The table [NASMSPAINT].[Ignition].[dbo].[booth_Styles] is a linked server. The User account I am using has enough permissions because I am able to UPDATE the table using Python. This is on a secure isolated network so security is of very little concern, this just needs to work using VB6 with ADO. Long story short, this code is part of a large application still using VB6 and rewriting the code in Visual Studio is not an option.
Using ADODB.Recordset.OPEN using adLockOptimistic option, the following error occurs on the ".Update" line of the code:
SQL server error message 16964 - for the optimistic cursor, timestamp columns are required if the update or delete targets are remote.
Using ADODB.Recordset.OPEN using adLockPessimistic option, the following error occurs on the ".Update" line of the code:
SQL Server Error Msg 16963 – You cannot specify scroll locking on a cursor that contains a remote table.
I have found very little information on the internet concerning these errors. I have set the following server option properties on the linked server on the database:
Collation Compatible: TRUE
Data Access:TRUE
RPC:TRUE
RPC Out:TRUE
Use Remote Collation:FALSE
Collation Name:
Connection Timeout:0
Query Timeout:0
Distributor:FALSE
Publisher:FALSE
Subscriber:FALSE
Lazy Schema Validation:FALSE
Enable Promotion of Distributed Transaction:TRUE
VB6 code:
sDBName = "PROVIDER=SQLOLEDB.1;Data Source=192.168.2.70;User ID=xxxx;Password=xxxx;Persist Security Info=False"
Dim Conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set Conn = New ADODB.Connection
Conn.Open sDBName
Set rs = New ADODB.Recordset
With rs
.Open "SELECT * FROM [NASMSPAINT].[Ignition].[dbo].[booth_Styles] WHERE [Booth] = 'AdPro' ORDER BY [StyleID]", Conn, adOpenDynamic, adLockOptimistic
.MoveFirst
nThisStyle = 1
Do Until .EOF
![Plant_Number] = Style_Data(nThisStyle).PlantStyle
![Style_Number] = Style_Data(nThisStyle).FanucStyle
![Descript] = Style_Data(nThisStyle).StyleDesc
![Robots_Required] = Style_Data(nThisStyle).StyleRobotsReq
.Update
.MoveNext
nThisStyle = nThisStyle + 1
Loop
End With
The code breaks on the .Update line.
My ultimate goal is to run sql queries against sql-server and capture the returned data in a spreadsheet. The following code roughly reflects my current set-up and it works. The design allows me to read sql codes from text files and submit it to a sql-server. "Sub ExecuteCRUD" submits a first sql script to prepare data and dumps the result into a temp table. "Function loadRecordset" submits a relatively simple select query and captures the returned data in a recordset, which I then use to populate a spreadsheet.
There are a couple "variables" in my setup that could potentially be relevant for discussion.
My 4 set of Sql Codes
The ConnectionString (Part of my vba code)
The rest of my vba codes
a. Dbo.ConnectionString = "Provider=MSDASQL;DRIVER=SQL
Server;SERVER=myserver;UID=id;PWD=password;DATABASE=database;"
b. Dbo.ConnectionString = "Provider=SQLOLEDB;Data
Source=myserver;Initial Catalog=database;User
ID=id;Password=password;"
Initially, all I changed was the connection string. The immediate result was connection string version a works perfectly. Using b version, my setup would fail without any errors from sql-server.
Using Connection string version b, "Sub ExecuteCRUD" (data preparation step) would still work smoothly. I can verify that the temp table is created in tempdb as a result of my first sql script.
"Function loadRecordset" would run through the lines without any errors up to and including "rs.open". (I checked for errors, none whatsoever from the ado connection).
Only subsequent codes, when using the recordset to copy out the data would get an error: "Operation is not allowed when the object is closed."
Through some testing, I narrowed down the issue to the sql codes, sort of.
I have to reiterate here. My initial set of sql codes worked completely fine when using the ODBC provider. Things only went sideways using the OLEDB provider.
Using the OLEDB provider, the "offending" sql code was Use databaseABC. Furthermore, using ado, my setup submits 4 sets of sql codes to the sql server. The first set of sql codes prepares data (creating tables, inserting data, creating index, using while loops to populate data, using recursive ctes, etc). In this first set of sql codes, Use databaseABC was also included, and it would execute successfully. The other 3 set of sql codes submitted were only select queries aimed at obtaining data. When Use databaseABC was included in the select query sql codes, the operation failed without any errors. After I took out the Use databaseABC, everything would run correctly in the OLEDB provider world.
Use databaseABC is not a necessary part of the select queries. Using it saves me the trouble of specifying database names all the time in the join clauses.
At this point, my curiosity is two fold
why Use databaseABC causes failures, specifically only when using OLEDB provider, more specifically only when running select queries.
When the failure occurred, should sql-server or the driver generate any errors? What would be the proper way of checking and verifying that?
Private Dbo As New ADODB.Connection
Private rs As ADODB.Recordset
Public Sub ConnectServer()
If Dbo.State = adStateClosed Then
Dbo.ConnectionString = "Provider=SQLOLEDB;Data Source=*server*;" _
& "Initial Catalog=*database*;User ID=*id*;Password=*pwd*;"
Dbo.Open
End If
End Sub
Public Sub ExecuteCRUD(ByVal Sql As String)
On Error GoTo PANIC
Dbo.Execute Sql
Exit Sub
PANIC:
Debug.Print Err.Descript
Stop
End Sub
Public Function loadRecordset(ByVal Sql As String) As Long
On Error GoTo PANIC
Set rs = New ADODB.Recordset
With rs
.CursorLocation = adUseClient
.CursorType = adOpenStatic
.LockType = adLockReadOnly
.Source = Sql
Set .ActiveConnection = Dbo
End With
rs.Open
loadRecordset = rs.RecordCount
Exit Function
PANIC:
Debug.Print Err.Description
loadRecordset = 0
Stop
End Function
I am trying to run the following in order to get the file name that the user selects. The file is an .mdf file that is attached previously to an SQL server. But when I run it, a window comes out and says I don't have permission to open the file. I know it is because it is being used in SQL, because if I don't attach it in the SQL server it runs without a problem.
The thing is that I need the mdf in SQL before running the vba code and I just need the file name. Is there a way to store the file name without "opening" it?
Function GetDB() As String
Dim db As Office.FileDialog
Dim fileName As String
Set db = Application.FileDialog(msoFileDialogFilePicker)
With db
.Title = "Select a Database"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
Application.DisplayAlerts = False
If .Show = True Then
fileName = Mid(.SelectedItems(1), InStrRev(.SelectedItems(1), "\") + 1)
End If
End With
End Function
replace
sItem = .SelectedItems(1)
with:
GetDB = .SelectedItems(1)
I ended up setting and ADODB Connection to get the databases directly from the server without having the "The file is in use" issue.
I have a job stored on a database, scheduled to run every day. But its sometimes necessary to want to execute this job at any given time to view up to date data (I'm using SQL Server Management Studio 2008).
The job itself simply takes data from a view which contains live data and puts it into a table which will then be used as a data source for an excel file. Executing the job drops and re-creates the table with fresh data.
In excel (2010), i wish to have a 'button' which which pressed will execute the job and then hitting refresh on the data tab in excel will then update the data on the sheet with the fresh data.
My question is: How do i execute this job from an excel macro?
Private Sub CmdRunJob_Click()
Dim con As Object
Set con = CreateObject("ADODB.Connection")
con.Open = "DRIVER={SQL Server};SERVER=YourServer;" & _
"USER=YourUser;PASSWORD=YourPassword;"
con.Execute "exec msdb.dbo.sp_start_job 'YourJob'"
End Sub
You create a SP that moves data from view to table.
Then modify the Job that it executes that SP by schedule.
Then in Excel Macro you can just use that SP to update the data.
Or see example how to run the Job from VBScript
You can use SQLDMO.SQLServer to execute your job.
Do any sql ninja's know how to execute a script (.sql) from within another script? Specifically for the Sql Server 2005+ platform. E.g. psudeo code follows:
ScriptA contents
RESTORE DATABASE [MyDbName]
FROM
DISK = N'path' WITH FILE = 1
.......
GO
Exec c:\scripts\ScriptB.sql
ScriptB contents
USE [MyDbName]
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MyTableName]') AND type in (N'U'))
CREATE TABLE [dbo].[MyTableName]
........
GO
You can turn SQLCMD mode on from SSMS or run your script in SQLCMD.exe.
SQLCMD supports script variables and script references.
---script1-----
create table ....
:r path/to/another/script (which can reference others)
---------------
hope this helps
The following article provides examples of how you can achieve this.
http://www.sqlservercentral.com/articles/Administering/scriptrunner/292/
Here is a free tool that can run multiple scripts but not from within an existing script.
http://www.xsqlsoftware.com/Product/ProductDetails.aspx?ProdID=ScriptExecutor
Here is an example of executing a script from within another script by calling the isql utility using the xp_cmdshell stored procedure.
http://www.sqlservercentral.com/articles/Administering/scriptscheduling/450/
Should be what you need to get going but drop me a line if you need further assistance.
Cheers, John
Core MS SQL doesn't do this, but some tools have some macro capabilities (i.e. done client site).
SQLCMD supports ":r" to import another file.
As far as i can see you dont have to combine the two scripts. You can just execute the first and then the other.
You can do this by making a vbscript that loads the .sql files and then uses an ADODB.Connection to execute the two scripts.
This vbscript should do it:
Set con = CreateObject("ADODB.Connection")
con.ConnectionString = "*** Database connection string here ***"
con.Open
Set fso = CreateObject("Scripting.FileSystemObject")
Set sqlFile = fso.OpenTextFile("scriptA.sql", 1)
con.Execute sqlFile.ReadAll
sqlFile.Close
Set sqlFile = fso.OpenTextFile("scriptB.sql", 1)
con.Execute sqlFile.ReadAll
sqlFile.Close
Set fso = Nothing
Set con = Nothing