I am new to VBScript. Can someone please help me to connect to SQL Server 2005 (OLEDB) using VBScript and update a table in the database.
My server: sql14\qw
My database: fret
User id: admin
Pasword: pass
Table name: lookup
Const DB_CONNECT_STRING = "Provider=SQLOLEDB.1;Data Source=sql14\qw;Initial Catalog=fret;user id ='admin';password='pass'"
Set myConn = CreateObject("ADODB.Connection")
Set myCommand = CreateObject("ADODB.Command" )
myConn.Open DB_CONNECT_STRING
Set myCommand.ActiveConnection = myConn
myCommand.CommandText = "UPDATE lookup SET Col1 = 'Hello'"
myCommand.Execute
myConn.Close
Tested using Integrated Windows Security, did not test with SQL Login.
Easy stuff, actually. First, you have to define the connection and recordset that you'll be using:
Set AdCn = CreateObject("ADODB.Connection")
Set AdRec = CreateObject("ADODB.Recordset")
After that, it's all about the connection string:
connstr="Provider=SQLOLEDB.1;Data Source=" & server & ";Initial Catalog=" & database & ";user id = '" & uid & "';password='" & pwd & "'"
The string consists of a few parts:
Provider: the type of connection you are establishing, in this case SQL Server.
Data Source: The server you are connecting to.
Initial Catalog: The name of the database.
user id: your username.
password: um, your password. ;)
Note that if you want to use your Windows login credentials and are running the script locally then you can substitute the following for the username and password fields:
Integrated Security=SSPI
Of course, this won't work if you're using your script on a website, so you'll have to explicitly use username and password. Then, making sure your connection is open, you just open the recordset, hand over the SQL query, and capture the returned data as an array.
SQL="Select ##version as name"
AdCn.Open connstr
AdRec.Open SQL, AdCn,1,1
queryReturn=Adrec("name")
Just remember that the data is being returned as an array (often two dimensional, where the results you want are actually in the second dimension of the array!) and that you may need to either Trim to kill blank spaces at the end of results or parse the results with string functions like Left. Personally, I always Trim() a result while assigning it to a variable as I've been bitten by hidden blanks more times than I can count.
Related
I am currently trying to connect to an Oracle database from VBA. Below is the code I am running in VBA to try to establish the initial connection. Unfortunately, this code produces an “ORA-01017” error mentioning that my username/password is invalid. I have SQL Developer installed and when I try to login with the same credentials/info, I successfully connect. I also tried instead setting UID = userid in the VBA code below and the connection didn’t throw an error, but I can’t query any tables. The same thing happens if I try the same in SQL developer.
After doing some reading, it looks like the info in the brackets is my proxy user id and I need to somehow specify that separately from my UID, but I can’t figure out how I would go about that. Has anyone else had any experience with this or have any guidance? Let me know if there is any additional details I can provide.
Sub Ora_Connection()
Dim con As ADODB.Connection
Dim rs As ADODB.recordset
Set con = New ADODB.Connection
Set rs = New ADODB.recordset
StrCon = "Driver={Microsoft ODBC for Oracle}; Uid=userid[database name];Pwd=UserPWD;" & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=TCP)" & _
"(HOST=HostName)(PORT=1521))" & _
"(CONNECT_DATA=(SERVICE_NAME=XXXX)));"
con.Open (StrCon)
End Sub
It doesn't look like its possible to connect to proxy user with ADODB .
One another alternative is to use alter session set current_schema = Proxy_user run this after you open the session.
The only trouble with this is that the grants should be there for the actual user, here proxy user just allows us to avoid using identifiers.
I am working on an Excel file that connects to a SQL database to update parameters on a piece of production machinery based on an analysis of part quality data. The file has been working in production for some time but a recent hacking attack on my company has caused us to review the security of all of our systems.
The old file version used ADODB with a hard-coded user name a password with narrowly defined database permissions. This meant any quality or engineering employee could run the Excel utility without being explicitly given server/database access. With our new security review, I wanted to switch the file to use windows authentication but I ran into some issues. It seems that using windows authentication through ADODB requires not just a database user, the automation team has permissions to create, but also a server login mapped to the database user which only an IT admin can create. I also worry that adding a large number of server-level users is not a wonderful idea.
The actual piece of production equipment uses a system-level ODBC connection with window authentication. This connection works fine with a database user without a server login. Because ODBC doesn't seem to need a server login it would make the management of the Excel file users much simpler and would allow the team in charge of the equipment and its database to handle it without IT.
Unfortunately, I have been unable to figure out how to execute queries and get results in VBA with an ODBC connection. I have tried Workbook.Connections("ODBCName").CommandText with an ODBC connection stored in the workbook but I don't see a way to directly get the result. The only option I can see is to map the query to cells in a hidden table and read them in VBA but this seems hackish. Also, I'm not sure how this would work for the results of queries other than SELECT like INSERT or UPDATE.
Any help would be greatly appreciated. An example of my old code is here, there are more routines that make similar queries:
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
strSQL = "SELECT * FROM Table.dbo.PART_INSPECTION_LOG WHERE PART_NUM = 'PartNo' AND DATA_TIME = " & dataTime
rs.Open strSQL, cn
If (rs.BOF And rs.EOF) = True Then
linear_err = (Sheets("Adjustment").Range("E24").Value)
rotational_err = (Sheets("Adjustment").Range("N24").Value)
strSQL = "INSERT INTO Table.dbo.PART_INSPECTION_LOG (PART_NUM, TOOL_ID, USER_NAME, DATA_TIME, LINEAR_ERROR, ROTATIONAL_ERROR) VALUES ('PartNum', 'ToolNum', "
strSQL = strSQL & "'" & Application.UserName & "', "
strSQL = strSQL & dataTime & ", "
strSQL = strSQL & linear_err & ", "
strSQL = strSQL & rotational_err & ")"
cn.Execute strSQL
End If
cn.Close
I would like to set up a vba code that would connect to sql management studio 2012 a run the query, which I would specify in the vba code. I have read every similar question here on stack overflow but when I try to replicate them, I always get an error, ussualy that the login failed for user.
I think I am setting up the string connection wrong. Also, I would need the user authentication by Windows authentication.
I know the database name, server name and my user name.
This is the code I am using and which is giving me an error.
Sub ConnectionExample6()
Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cnn = New ADODB.Connection
' Open a connection by referencing the ODBC driver.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=SERVER NAME;uid=USER ID;pwd=MyPassword;database=DATABASE NAME"
cnn.Open
' Create a Recordset by executing an SQL statement.
Set rs = cnn.Execute("Select top 100 * from "TABLE NAME" aac " & _
"where aac.EffectiveDate = '10/04/16'")
' Close the connection.
rs.Close
End Sub
Can someone walk me through the connection string and how to set it up step by step? Thank you.
Authentication
If you're connecting to SQL Server, you should prefer Windows Authentication if that's available: you create a Login at server level for a group of Active Directory users, and then you create a Windows-Authenticated User in your database using that login.
That way you are keeping passwords and usernames out of hard-coded strings, and let the network deal with authentication.
Assuming you don't want to be maintaining passwords in dozens of copies of macro-enabled workbooks across your network, you'll want to use Windows Authentication.
Integrated Security=SSPI; Persist Security Info=True;
Server
Connection strings are annoying - seems there's a different format/wording for every single different thing that's able to parse them!
Since you're using ADODB, you'll want to specify a Provider, a Data Source and, optionally, an Initial Catalog:
Provider=SQLOLEDB.1; Data Source=SQL Server instance name; Initial Catalog=Database name;
Who?
Each connection can be monitored on the server; when building your connection string you can optionally specify a Workstation ID to identify the machine the connection is for.
Workstation ID=computer name;
You can get the computer name by fetching the environment variable value, using Environ$:
Private Function GetWorkstationId() As String
GetWorkstationId = Environ$("ComputerName")
End Function
Given a SQL Server instance named SomeSqlServer, a database named SomeDatabase, and using Windows Authentication, the ADODB connection string would look like this:
Dim connString As String
connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; Integrated Security=SSPI; Persist Security Info=True;"
Given SQL Authentication (with a hard-coded user name and password) for SomeUser with SomePassword:
connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; UID=SomeUser; PWD=SomePassword;"
Commands
You don't want to be concatenating arbitrary user input into a WHERE clause; avoid executing an SQL string directly from the ADODB.Connection object.
Instead, create an ADODB.Command, and parameterize your query.
Dim sql As String
sql = "SELECT Foo, Bar FROM dbo.FooBars WHERE Foo = ? AND DateInserted > ?"
Here we have 2 parameters.
First we create the command:
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = sql
Then its parameters, assuming we have their respective values in param1Value and param2Value local variables:
Dim param1 As ADODB.Parameter ' a string parameter
Set param1 = New ADODB.Parameter
param1.Type = adVarWChar
param1.Direction = adParamInput
param1.Size = Len(param1Value)
param1.Value = param1Value
cmd.Parameters.Append param1
Dim param2 As ADODB.Parameter ' a date parameter
Set param2 = New ADODB.Parameter
param2.Type = adDate
param2.Direction = adParamInput
param2.Value = param2Value
cmd.Parameters.Append param2
Then we retrieve the recordset by executing the command:
Dim results As ADODB.Recordset
Set results = cmd.Execute
Of course this looks very verbose, but it can easily be refactored into functions dedicated to creating a parameter given a value of a certain type.
As a result, you avoid this situation, because you're no longer executing arbitrary user input concatenated into a query:
I'm trying to use VBA from Excel 2007 to execute a query in an Access 2007 DB as a stored procedure. The query retrieves data from a few MS SQL tables linked via an ODBC DSN. The authentication for the external tables is done with Windows NT authentication with Trusted_Connection=Yes
I have tried connecting to the linked tables with both a User and System DSN - either way works fine when I run the query from Access 2007.
When I try using VBA in Excel the data that should be coming from the Windows authenticated tables isn't retrieved. I am able to retrieve data from a set of linked MS SQL tables that are using a stored UID.
Here is the connection string I'm using:
strDB = xlWb.Path & "\database\dbQueries.accdb"
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strDB & ";"
And here is the command that's only partially successful (with data from the UID authenticated tables):
With cmd2
.ActiveConnection = conn
.CommandText = "qryAppendtblOutput"
.CommandType = adCmdStoredProc
.Parameters.Append cmd2.CreateParameter("[Start Date]", adDBDate, adParamInput, , startDate)
End With
cmd2.Execute
Thanks very much in advance!
I have been able to resolve this issue by switching to the Access ODBC driver instead of the OLE DB provider. I changed my connection string to:
strDB = xlWb.Path & "\database\dbQueries.accdb"
conn.Open "Driver={Microsoft Access Driver (*.mdb, *.accdb)};" & _
"Dbq=" & strDB & ";" & _
"Trusted_Connection=Yes;"
Then, all I had to do was adjust the syntax of the underlying queries in Access to meet the requirements of this driver (I had to replace all double quotes with singles).
Thanks very much to all who reviewed my question :)!
I've got this code I'm trying to use to export data from Excel to an SQL Database and I'm receiving this error when I try to open the connection.
[Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for the user 's_accounting'
This is the code I'm trying to use(variables already Dimmed of course)
ServerName = "192.168.168.34"
DatabaseName = "Accountingnumbers"
TableName = "Projects"
UserID = "s_accounting"
Password = "password123"
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open "Driver={SQL Server};Server=" & ServerName & ";Database=" & DatabaseName & _
";Uid=" & UserID & ";Pwd=" & Password & ";"
Note that I've renamed some sensitive stuff in there. Also, I've set the permissions on the database using this SQL Query:
use [db]
go
create user [myDomain\Groupname] for login [myDomain\Groupname]
go
grant select on schema::dbo to [myDomain\Groupname]
go
The user I'm trying to connect with (s_accounting) is member of a domain group, which is granted access to the database using the query above.
Any ideas or suggestions? Do I have to specifically give permissions to each table as well?
You're mixing two authentication methods - you created/enabled AD (domain) user, but you're using SQL authentication to access server.
Either you need to access server with current domain user credentials (so called integrated security; cannot present correct syntax atm) OR you need to enable SQL authentication on SQL server (if not enabled already) and create user "accounting" (and other needed ones) with specific passowrd.