Multi database query ACCESS and SQL SERVER - database

I'm not able to figure out how to make a multi database query usign two diffent ditabase.
The first database is an ACCESS mdb database and the second one is a SQL Server 2012 database.
I'm using Visual Basic 6.
The code I'm using is that:
ConnectionString1 = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=C:\MyDatabase.mdb"
ConnectionString2 = "DSN=ODBC_NAME;UID=user;PWD=password"
SQL = "SELECT tabScheda.sWorkNum FROM tabScheda WHERE codScheda NOT IN" + _
" (SELECT ORDERID FROM [" + ConnectionString2 + "].V_PRESETTING_SP_HEADER WHERE MODE = 'TC')"
cn.Open ConnectionString1
Set rc = cn.Execute(SQL)
rc.Close
Set rc = Nothing
cn.Close
Set cn = Nothing
Please help me :D

Related

Using VB6 with ADO to access a MS SQLServer 2019 linked server

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.

Import MS-SQL data into an Access Table ADO

I hope that you can help me or point me in the right direction. For many years, I have used a very clean and simple method of importing data (within VB6, yes!) from a MS-SQL table into an MS-Access database/table as follows:-
WORKING QUERY WITH NO INNER JOINS
Dim myConnection As ADODB.connection
Dim mySQL As String
Set myConnection = New ADODB.connection
myConnection.Open "Driver={Microsoft Access Driver (*.mdb)};" & "Dbq=DB1.mdb;" & "DefaultDir=C:\Temp;" & "Uid=Admin;Pwd=;"
mySQL = "SELECT * INTO [Xray] FROM [ODBC;Driver=SQL Server; SERVER=myServer;DATABASE=myDatabase;UID=myUID;PWD=myPassword;].[ShipTo] WHERE [ShipTo].Company='ABC001'"
myConnection.Execute mySQL
Set myConnection = Nothing
However, for the first time, I now need to start working with Inner Joins. I thought that I could do something as simple as above, but I have come unstuck rather heavily and have no idea how to progress. My Inner Join query is below:-
SELECT
dbo.InvcHead.InvoiceNum AS DocNum,
SUM(dbo.InvcTax.TaxAmt) AS DocTaxAmt
FROM
dbo.InvcTax
INNER JOIN
dbo.InvcHead ON (dbo.InvcTax.InvoiceNum = dbo.InvcHead.InvoiceNum)
GROUP BY
dbo.InvcHead.InvoiceNum**
Because of my clear lack of experience using joins with my tried and tested method, I get an error which is probably because of my syntax, but I just cannot see the light. Below is the new connection string/query attempt:-
FAILED QUERY WITH INNER JOINS
Dim myConnection As ADODB.connection
Dim mySQL As String
Set myConnection = New ADODB.connection
myConnection.Open "Driver={Microsoft Access Driver (*.mdb)};" & "Dbq= DB1.mdb;" & "DefaultDir= C:\Temp;" & "Uid=Admin;Pwd=;"
mySQL = ""
mySQL = mySQL & "SELECT "
mySQL = mySQL & "dbo.InvcHead.InvoiceNum AS DocNum, "
mySQL = mySQL & "SUM(dbo.InvcTax.TaxAmt) As Doctaxamt "
mySQL = mySQL & "INTO [Xray] FROM [ODBC;Driver=SQL Server; SERVER= myServer;DATABASE= myDatabase;UID= myUID;PWD=myPassword;].[dbo.InvcTax] "
mySQL = mySQL & "Inner Join dbo.InvcHead ON (dbo.InvcTax.InvoiceNum = dbo.InvcHead.InvoiceNum)"
mySQL = mySQL & "Group By dbo.InvcHead.Invoicenum"
myConnection.Execute mySQL
Set myConnection = Nothing
The error message I get is "Syntax Error in Join Operation"
Is it possible to do this extraction using this method with an inner join query? I suspect my problem relates to the area of the script where I reference the first table of the join.
.[dbo.InvcTax] "
If this is not possible, is there a way to create a table dynamically (as I have done) but from a recordset instead?
Any help of a steer in the right direction will be massively appreciated.
Thanks,
Jack
The dbo prefix fails in Access SQL and you miss the database reference for the second table:
mySQL = ""
mySQL = mySQL & "SELECT "
mySQL = mySQL & "T1.InvoiceNum AS DocNum, "
mySQL = mySQL & "SUM(T1.TaxAmt) As Doctaxamt "
mySQL = mySQL & "INTO [Xray] FROM [ODBC;Driver=SQL Server;SERVER=myServer;DATABASE=myDatabase;UID=myUID;PWD=myPassword;].dbo.InvcTax AS T1 "
mySQL = mySQL & "INNER JOIN [ODBC;Driver=SQL Server;SERVER=myServer;DATABASE=myDatabase;UID=myUID;PWD=myPassword;].dbo.InvcHead AS T2 ON (T1.InvoiceNum = T2.InvoiceNum)"
mySQL = mySQL & "Group By T2.Invoicenum"

How to read SQL Always-encrypted column from classic ASP

I maintain a classic ASP app (yeah, I know, we're working on it) and need to access Always Encrypted columns in SQL 2017.
I've imported the cert and tested in SSMS and PowerShell and that much works. The best I've been able to do in ASP is to get the encrypted value as a byte array. I've tried more connection string combinations than I can remember.
My ASP dev box is Windows 10; the data server is SQL 2017.
cnn = "Provider=MSOLEDBSQL; DataTypeCompatibility=80; " _
& "DRIVER={ODBC Driver 17 for SQL Server}; " _
& "SERVER=xxxx; UID=xxxxx; PWD=xxxxx; DATABASE=xxxx; " _
& "ColumnEncryption=Enabled; Column Encryption Setting=Enabled;"
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = Server.CreateObject("ADODB.Command")
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()
The code works without error but the encrypted column (Enc, varchar(50)) is returned as a byte array. I seem to be getting the encrypted value when I should get the plain text value. I've also tried calling a Stored Procedure with the same results. No filter in the query, so nothing to parameterize.
Any ideas what to try next?
Answer:
1) Import the cert as the same user as the AppPool Identity for that web app.
2) Set Anon authorization for the web app to Application Pool Identity.
3) Use this connection string:
cnn = "Provider=MSDASQL;" _
& "Extended Properties=""Driver={ODBC Driver 17 for SQL Server};" _
& "SERVER=***; UID=***; PWD=***;" _
& "DATABASE=***;ColumnEncryption=Enabled;"" "
The new Microsoft OleDb Provider for SQL Server (MSOLEDBSQL) doesn't support AlwaysEncrypted (currently). You'll have to use ODBC, which means the OleDb provider should be the Microsoft OleDb Provider for ODBC (MSDASQL). So you can either configure a system DSN using Microsoft® ODBC Driver 17 for SQL Server with a connection string like:
cnn = "Provider=MSDASQL;DSN=testdb;"
or embed all the ODBC driver parameters in the "Extended Properties" of the MSDASQL connection string. Like
cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "
Here's walkthrough, using first VBScript for testing before testing with ASP.
Starting with:
create database testdb
go
use testdb
create table tbl1(id int, Enc varchar(200))
insert into tbl1(id,enc) values (1,'Hello')
Then running through the column encryption wizard in SSMS, which stores the certificate on for the current user, on the machine running SSMS:
Then the listing of query.vbs:
cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = CreateObject("ADODB.Command")
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()
rst.MoveFirst()
msgbox( cstr(rst("Enc")) )
Which can be run from the commandline with:
cscript .\query.vbs
To do this from ASP you'll additionally have to place the certificate in the user certificate store of the IIS App Pool account, per the docs here. Note that the relative path to the certificate has to be the same for all users. You can't store it in the machine store on the IIS box if you initially configured it to be stored in the user's certificate store. SQL Server stores the key_path of the key and instructs the clients where to find the certificate, eg CurrentUser/my/388FF64065A96DCF0858D84A88E1ADB5A927DECE.
So discover the key path of the Column Master Key
select name, key_path from sys.column_master_keys
Then export the certificate from the machine that has it:
PS C:\Windows> $path = "cert:\CurrentUser\My\388FF64065A96DCF0858D84A88E1ADB5A927DECE"
PS C:\Windows> $mypwd = ConvertTo-SecureString -String "xxxxxxx" -Force -AsPlainText
PS C:\Windows> Export-PfxCertificate -Cert $path -FilePath c:\temp\myexport.pfx -ChainOption EndEntityCertOnly -Password $mypwd
Running as the app pool identity user on the IIS server, import it
PS C:\WINDOWS> $mypwd = ConvertTo-SecureString -String "xxxxxxx" -Force -AsPlainText
PS C:\WINDOWS> Import-PfxCertificate -FilePath C:\temp\myexport.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $mypwd
And if you're using Anonymous/Forms auth sure you've configured IIS Anonymous Auth to run under the App Pool identity, not the default IUSR.
Here's an ASP page to test with:
<!DOCTYPE html>
<html>
<body>
<p>Output :</p>
<%
Set objNetwork = CreateObject("Wscript.Network")
Response.write("The current user is " & objNetwork.UserName)
cnn = "Provider=MSDASQL;Extended Properties=""Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=testdb;Trusted_Connection=yes;ColumnEncryption=Enabled;"" "
Set oDB = CreateObject( "ADODB.Connection" )
oDB.Open cnn
set oCmd = CreateObject("ADODB.Command")
oCmd.ActiveConnection = cnn
oCmd.CommandText = "SELECT top 10 ID, Enc FROM tbl1"
set rst = oCmd.Execute()
rst.MoveFirst()
Response.write(cstr(rst("Enc")) )
%>
</body>
</html>

Querying MSSQL 2012 from VBSCRIPT using ADODB

I am having a hard time filling a recordset with data from an MSSQL 2012 server using ADODB.
Below is the code that is not working, along with the error I am receiving.
I have used this exact same setup to query data from an MSSQL 2008r2 server without issue.
I know that my SELECT statement is accurate and correct. If I take my select statement and paste it into a new query window in sql server management studio, it returns data.
Dim mConnection
Set mConnection = CreateObject("ADODB.Connection")
mConnection.Open "Provider=SQLOLEDB.1;Data Source=rwdwstage","SA","PASSWORDREDACTED"
Set Tech_RS = CreateObject("ADODB.Recordset")
SQLstr = "SELECT QDSTCD, QDAREA, QDBANK FROM [RWDATA].[dbo].[BRDETAIL] where QDSDT = '20151215' and QDSTCD = 'WI'"
Tech_RS.open SQLstr, mConnection
Do while not Tech_RS.EOF
wscript.echo Tech_RS.Fields("QDSTCD") & " - " & Tech_RS.Fields("QDAREA") & " - " & Tech_RS.Fields("QDBANK")
Tech_RS.MoveNext
Loop
Error Returned
cscript ..\HIST_Transfer\test2.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
..\HIST_Transfer\test2.vbs(11, 1) Microsoft OLE DB Provider for SQL Server: Incorrect syntax near the keyword 'FROM'.
Any help that could be provided would be extremely appreciated!
You can add Initial Catalog to connection string:
mConnection.Open "Provider=SQLOLEDB.1;Data Source=rwdwstage;Initial Catalog=RWDATA","SA","PASSWORDREDACTED"
and change query to:
SQLstr = "SELECT QDSTCD, QDAREA, QDBANK FROM [dbo].[BRDETAIL] where QDSDT = '20151215' and QDSTCD = 'WI'"
I guess that it worked before because the default database, for login you use for connecting, was RWDATA and with newer version it points to another DB (you can try to change default DB for that login and check if it works, be aware that changing it may broke other application that relies on default DB)

Microsoft OLE DB Provider for SQL Server error '80040e14' Incorrect syntax near '='

I get this error when i try to retrieve the data from database using the following piece of code.
Can someone help?
set rs = Server.CreateObject("ADODB.recordset")
sql = " SELECT * from COMPANY WHERE COMPANY_ID = " & Request.Form("CompanyId")
rs.Open sql, cnn
First of all, this is bad practice to do ad-hoc queries without using parameters. SQL Injection attack info: http://en.wikipedia.org/wiki/SQL_injection
To answer the question, though, you need to have single quotes around your varchar or char value that you are searching for.
set rs = Server.CreateObject("ADODB.recordset")
sql = " SELECT * from COMPANY WHERE COMPANY_ID = '" & Request.Form("CompanyId") & "'"
rs.Open sql, cnn

Resources