We have an Access UI to Sql Server database. The user connects to many databases (containing the same tables with different data), can choose between them. We use this for versioning. We want to make him able to copy and delete databases right from Access UI. He should be able to copy at least to the same server, and ideally also to other server.
A Backup and restore is probably going to be your best bet. There is another way as well. But there will be some restrictions.
You can detach the DB you want to copy, make a copy of the files attach the old one, and attach the new one as a new DB. Your problem will be because you are using Access to connect to the DB, you will not be able to detach it because there is a connection to it, and all connections must be dropped before you can detach it.
Dropping the DB (delete it) will have the same problem. It won't drop unless you there is no connections on the DB.
This is my final solution:
Dim conn As New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB;Data Source=" dbServer & ";" _
& "User ID=" & user & ";Password=" & password
conn.Open
' backup
conn.Execute "BACKUP DATABASE [" & sourceDb & "] TO [backup device] WITH NOFORMAT, NOINIT, NAME = N'backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10"
' restore
conn.Execute "RESTORE DATABASE [" & targetDb & "] FROM [abcosting temporary backup] WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10, " & mdf_move & ", " & ldf_move
Related
I am trying to copy a database file using file management concept in vb.
My code is:
IO.File.Copy(MukilCommon.APP_PATH & "\" & CurrentDbName & ".mdf", MukilCommon.APP_PATH & "\" & CurrentDbName & "_" & yearStr & ".mdf")
IO.File.Copy(MukilCommon.APP_PATH & "\" & CurrentDbName & ".ldf", MukilCommon.APP_PATH & "\" & CurrentDbName & "_" & yearStr & ".ldf")
My code is copied a database from new database on e:, like this:
sample.mdf
sample.ldf
sample_2016.mdf
sample_2016.ldf
I used this code for attach my copied database in SQL Server.
db1.Execute("EXEC sp_attach_db #dbname = '" & CurrentDbName & "_" & yearStr & "', #filename1 = '" & MukilCommon.APP_PATH & "\" & CurrentDbName & "_" & yearStr & ".mdf', #filename2 = '" & MukilCommon.APP_PATH & "\" & CurrentDbName & "_" & yearStr & ".ldf'")
But I get this message.
Can't attach a file name, "sample" database is already exists in SQL Server.
Actually the copied file has try to attached on original database. How to I attach this database?
My suggestions:
Put the files in different folders, you have to keep mdf and ldf files with the same name, use this script:
USE [master]
GO
CREATE DATABASE [Simple_2017] ON
( FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\2017\Simple.mdf' ),
( FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\2017\Simple_log.ldf' )
FOR ATTACH
GO
don't use sp_attach_db
As I could understand, you have data and log files of a detached database and you want to attach this database on a SQL Server instance.
From the error, I understand that there is already a database named "sample" on your SQL Server instance
So, if you want to attach a new database, you can choose a new name for your database to attach. Maybe you can call it sample2
Since you have already tried to detach, I could guess your data files are in a seperate folder than the existing sample database files exist
You can keep these files on seperate folders, so you can use the same fille names for example TestDB.mdf for both sample database and sample2 database
Then you can execute your code like
EXEC sp_attach_db #dbname = N'sample2',
#filename1 =
N'C:\NewDataFolder\TestDB.mdf',
#filename2 =
N'C:\NewDataFolder\TestDB_log.ldf';
I have a table in Access 2003 that is linked to a MS SQL server table.
I am able to go into the Access table, manually update it and see the changes
reflected in the MS Sql server table.
However, I'm unable to even just open the table and put the result in the record set in my VBA code.
Set rs = CurrentDb.OpenRecordset("dbo_tbl_EventLogs", dbOpenTable)
(rs is always at nothing)
The same line of code works on a 'local' Access table.
Consider using dbOpenDynaset option which is used by default for linked tables or stored queries whereas dbOpenTable is used for local tables as mentioned for OpenRecordset() method:
If you open a Recordset in a Microsoft Access workspace and you don't
specify a type, OpenRecordset creates a table-type Recordset, if
possible. If you specify a linked table or query, OpenRecordset
creates a dynaset-type Recordset.
Set rs = CurrentDb.OpenRecordset("dbo_tbl_EventLogs", dbOpenDynaset)
You need to connect to your DB using ADO. Is simple and easy. Just change to your info and enjoy it.
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
ServerName = "yourServer,yourPort(example: 1442)" 'Enter your server name and a port here
DatabaseName = "yourDBinTheServer" 'Enter your database name here
UserID = "yourUserID" 'Enter your user ID here
Password = "yourPassword" 'Enter your password here
Set rs = New ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open "Driver={SQL Server};Server=" & ServerName & ";Database=" & DatabaseName & ";Uid=" & UserID & ";Pwd=" & Password & ";"
rs.open yourQueryAsString, cn
Make sure you store the user credentials used to connect to the database...
(attribute dbAttachSavePWD)
In SQL server user have to follow below steps to restore database from backup file.
right click on the Databases container within object explorer.
from context menu select Restore database.
Specify To Database as either a new or existing database.
Specify Source for restore as from device.
Select Backup media as File.
Click the Add button and browse to the location of the BAK file.
Is there any script/command to restore the same without doing the above methods?
Just before you click on the last OK button on SSMS Backup/Restore Wizard ... you can Click on the script drop down button and pick script to New Query Window (The script drop down is Next to the Help button and above the Source/Database Name) and it will generate the Exact command that SSMS will execute against the DB. So you can use that command from the Query window to do the same thing programatically in TSQL. Indeed you can even put that inside a Stored PRocedure if you want to execute the same command all the time like so:
CREATE PROCEDURE dbo.dbBackup AS
BEGIN
RESTORE DATABASE [MyDataBaseName] FROM DISK = N'C:\SQLData\MyDB.bak'
WITH FILE = 1, NOUNLOAD, STATS = 5
END
And to take it one more level you could assign that SP to a hotkey as explained over here : https://www.mssqltips.com/sqlservertip/1287/assign-shortcuts-to-commands-in-sql-server-management-studio/
To access the screen below, open a query window and select from the menu Tools -> Options and then under the Environment node select Keyboard --> Query Shortcuts this will allow you to assign a stored procedure to execute for the Hotkey combination that is best for you.
One thing to be care full about though is to make sure that this does not replace an existing DB because you could accidentally overwrite a good DB if the restore command includes that option
"Automate" is a very broad term in your question, but if C# is an option, you can use the SQLCommand Class to execute the Restore, as below
sqlCmd.CommandText = "RESTORE DATABASE [" + restoreDbName + "] FROM DISK =
N'" + backupFileName + "' WITH FILE = 1, MOVE '" + logicalNameMdf + "' TO '"
+ restorePathMdf + "', MOVE '" + logicalNameLdf + "' TO '" + restorePathLdf + "', "
+ " NOUNLOAD, REPLACE";
sqlCmd.ExecuteNonQuery();
I would like to create a database in SQL server using VBA (Excel) just the first time that I will run the code. So the second time I run the code, the database will exist, and it will not create another one.
#abarisone
`Public Sub CreateDBTable()
Dim dbConnectStr As String
Dim Catalog As Object
Dim cnt As ADODB.Connection
Dim dbName As String
Dim tblName As String, ServerName As String, UserID As String, pw As String
tblName = shControl.Range("B5") 'Table Name
ServerName = "SERVICESWS15" 'Enter Server Name or IP
dbName = shControl.Range("B4") 'Enter Database Name
UserID = "" 'Leave blank for Windows Authentification
pw = "" 'Leave blank for Windows Authentification
dbConnectStr = "Provider=SQLOLEDB;Data Source=" & ServerName & ";Initial Catalog=" & dbName & ";User Id=" & UserID & ";Password=" & pw & ";"
Set Catalog = CreateObject("ADOX.Catalog")
Catalog.Create dbConnectStr
Set Catalog = Nothing
Set cnt = New ADODB.Connection
With cnt
.Open dbConnectStr
.Execute "CREATE TABLE " & tblName & " (KEY nvarchar(100) NOT NULL, " & _
"Date nvarchar(100) NOT NULL, " & _
"PRIMARY KEY (KEY));"
End With
Set cnt = Nothing
End Sub
`
There is an error in this line:
Catalog.Create dbConnectStr
Error: No such interface supported
It's not very complicated. First make sure that you are referring to the appropriate ADO library like here on the screenshot.
Then your have certain building blocks you will have to use: first make a Connection object (with a connection string), then make a Command object, and last but not least use the ExecuteNonQuery method of Command on your connection object. It does what the name says: executes an SQL command without having a RecordSet as a return object. See examples in the documentation starting from here.
I have not tried it before, but for this to happen without error, you will probably have to set your connection string to the system database called "Master" if working on MS SQL Server.
Of course, the SQL commands you will have to execute are (1) check if the database exists, (2) create db and tables if not.
Then you can create your "normal" Connection object to your database.
WARNING: to be able to create a database, your technical user defined in the VBA script must have high (system admin) privileges which is definitely a HUGE RISK even if you protect your excel. If it's not a sandbox environment, DO NOT DO IT!
We need to find a way to programatically ****link all the tables in a SQL Server database to an access db. We will be invoking this access database from a program that uses .net/SQL Server 2008.
While invoking the application we would like to add the linked tables so that the users can just run the reports/modules from access without having to worry about linking the tables. Is there a way we can do this?
Here are some notes.
Dim sLocalName As String
Dim tdf As TableDef
Dim rs As dao.Recordset
''This is a basic connection string, you may need to consider password and so forth
cn = "ODBC;DSN=TheDSNName;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=TheDatabaseName;"
''All fields from tables
strSQL = "SELECT TABLE_CATALOG, " _
& "TABLE_SCHEMA, " _
& "TABLE_NAME, " _
& "TABLE_TYPE " _
& "FROM [" & cn & "].INFORMATION_SCHEMA.tables " _
& "WHERE TABLE_TYPE = 'BASE TABLE'"
Set rs = CurrentDb.OpenRecordset(strSQL)
Do While Not rs.EOF
sLocalName = rs!TABLE_SCHEMA & "_" & rs!TABLE_NAME
With CurrentDb
If DLookup("Name", "MSysObjects", "Name='" & sLocalName & "'") <> vbNullString Then
If .TableDefs(sLocalName).Connect <> cn Then
.TableDefs(sLocalName).Connect = cn
.TableDefs(sLocalName).RefreshLink
End If
Else
''If the table does not have a unique index, you will neded to create one
''if you wish to update.
Set tdf = .CreateTableDef(sLocalName)
tdf.Connect = cn
tdf.SourceTableName = rs!TABLE_NAME
.TableDefs.Append tdf
.TableDefs.Refresh
''This will produce a message box if the table does not have a unique index
''DoCmd.TransferDatabase acLink, "ODBC Database", cn, acTable, rs!TABLE_NAME, sLocalName
End If
End With
rs.MoveNext
Loop
You'll need an ODBC connection to the SQL database. Once this connection ready, you can use it for all tables that you want to link:
DoCmd.TransferDatabase acLink, _
"ODBC Database", _
myODBCconnection, _
myDatabaseName, _
acTable, _
myTableName
I guess you can declare your ODBC connector "on the fly", as proposed here for example.
To enumerate your tables, you have the following options:
Enumerate them in the code: one transferDatabase line per table
Save the table names in a local table, and browse the table
Save the table names in a file (text, xml) anywhere on the network and browse the file
Access the system table on the server that holds the table list, and browse the table
Use the ADOX object to browse all tables in your database server: be carefull not to include system tables. This solution might be also quite confusing because you'll have to first open an ADODB connection to your database, and you'll then use an ODBC connection to open the tables
In all cases, this procedure shall be launched with the autoexec macro, meaning that links will be created\updated each time the user opens the mdb client.
You would use ADOX to do the actual linking.
As far as enumerating the tables in a database you are connected to, you could do something as simple as running this query against your SQL Server, but there are a lot of ways to skin that cat:
SELECT * FROM INFORMATION_SCHEMA.TABLES
You can achieve the equivalent by using a Linked Server in SQL Server that points to the Access db. This will give you access to all the tables in the Access db so that you can reference them like:
Select ..
From [LinkedServerName]...[AccessTableName]
Btw, a linked server may be overkill for what you want. Look into the OPENROWSET function which effectively let's you pass a connection string.
EDIT: I originally read the question to literally mean "link tables in SQL Server to access" which I translated to mean from SQL to Access. So, given that, my solution would apply. However, if the desire is to go from Access to SQL, then that is different and other solutions presented would be more appropriate.