I have an application for managing pharmacies (just an example ) this application is developed so that it relates to a single pharmacy . This application map on a Micrsoft DBMS MSSDE
each pharmacy generates database file ( pharmacy.mdf , pharmacy_log.mdf )
So after getting these files from different pharmacies, I wrote a script to automate data extraction from these all files
As the application is running, the script do the following tasks:
- Stops the server MSSQL server
- copy the two files from folder files recover and paste them in the path of the application
- Restart the server
- exctract the desired data
the connection with the database in question is using the python pyodbc Module
Once the extraction is run at a certain time pyodbc crash
i gotte this error:
cursor.execute ('select * from Pha.dbo.table_test ')
pyodbc.Error : ( '01000 ',' [ 01000 ] [ Microsoft] [ODBC SQL Server Driver] [ Shared Memory] ConnectionWrite ( ( send () ( 10054 ) ( SQLExecDirectW ) ')
i wrote this code for connection:
log = os.path.join(path,c,"SIC_log.ldf")
mdf = os.path.join(path,c,"SIC.mdf")
print(log)
print(mdf)
subprocess.call('net stop mssqlserver')
time.sleep(2)
os.system('copy "' + log + '" "' + MSSQL_DIR+'"')
os.system('copy "' + mdf + '" "' + MSSQL_DIR+'"')
time.sleep(2)
subprocess.call('net start mssqlserver')
time.sleep(2)
# Open a connection with the database
cnxn = pyodbc.connect('DSN=SIC_ODBC')
time.sleep(2)
extract_clo(cnxn, wb, ws)
cnxn.close()
Related
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 have a PowerShell block that runs fine in the PowerShell window but when I put the same exact code into SQL Server Agent job step and try to execute it it failed with the following message.
Date 27.6.2015 1:00:00
Log Job History (JobName)
Step ID 1
Server ServerName
Job Name JobName
Step Name Step1
Duration 00:00:00
Sql Severity 0
Sql Message ID 0
Operator Emailed
Operator Net sent
Operator Paged
Retries Attempted 0
Message
Unable to start execution of step 1 (reason: line(46): Syntax error).
The step failed.
Below is the offending code
$text = $table | Where-Object {$_.Pending_Messages -gt $threshold} | Out-String
$html = "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd""><html xmlns=""http://www.w3.org/1999/xhtml""><head>$style</head><body>$name <br />$warning<br /><br /><table><tr><td>Pending_Messages</td><td>Transaction Profile ID</td><td>Description</td><td>name</td><td>Last Activity</td><td>Address</td><td>Minimum Sent Time</td><td>Awake</td></tr>"
foreach ($Row in $table.Rows) {
if ($($Row[0]) -gt $threshold) { # <--- This is line 46
$ToSend = 1
write-host "value is : $($Row[0])"
$html += "<tr><td>" + $row[0] + "</td><td>" + $row[1] + "</td><td>" + $row[2] + "</td><td>" + $row[3] + "</td><td>" + $row[4] + "</td><td>" + $row[5] + "</td><td>" + $row[6] + "</td><td>" + $row[7] + "</td></tr>"
#break
}
}
What went wrong?
You haven't said what version of SQL Server or Windows OS you're running, but the Agent runs its own version of powershell that's distinct from whatever you may have installed.
On SQL Server 2012, sqlps utility launches PowerShell 2.0
On SQL Server 2008/2008R2, sqlps utility launches PowerShell 1.0
So, you may be using a syntax feature that's only available in a later version of powershell than what your Agent is running, which is why you get the Syntax error message.
I'm working on an app that is using a database that is encrypted by sqlcipher. The passwort for this encryption is stored by cacheword.
To make a backup of my database I used the following code:
// ggf. Datenbank öffnen
openGuard();
mDb.execSQL("ATTACH DATABASE '" + outFileName + "' AS backup KEY 'asdfghjkl';");
mDb.rawExecSQL("SELECT sqlcipher_export('backup');");
mDb.execSQL("DETACH DATABASE backup;");
The method openGuard() is used to check if the database is opend yet and if not do this.
I've checked the backup by using an empty key to make an unencrypted copy of my database. Then I can use it on adb shell and use sql-statements to get the wanted data.
My problem now for a long time is that I'm not able to use my backup to restore the database of my app. I tried this code:
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(backupFile, "asdfghjkl", null);
db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '" + mCacheWord.getEncryptionKey() + "';");
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");
Alternatively I tried
db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '" + encodeRawKey(mCacheWord.getEncryptionKey()) + "';");
But in both cases I get the following error message:
10-30 00:56:42.845: I/Database(14407): sqlite returned: error code = 26, msg = statement aborts at 5: [ATTACH DATABASE '/data/data/.../databases/database.db' AS encrypted KEY '[B#42082da0';] file is encrypted or is not a database
10-30 00:56:42.845: E/Database(14407): Failure 26 (file is encrypted or is not a database) on 0x63bdedb0 when executing 'ATTACH DATABASE '/data/data/.../databases/database.db' AS encrypted KEY '[B#42082da0';'
Is there anyone how can help me with my problem?
Looks like you've gotten accidentally "hung up" trying to decrypt by supplying the key via the ATTACH DATABASE statement. Looking at Example 2: Decrypt a SQLCipher database to a Plaintext Database of the API, there's a comment that reads -- empty key will disable encryption. So, presumably your initial decryption code attempt should first execute the PRAGMA key = statement (to supply the key) and then the ATTACH DATABASE statement with empty key (to decrypt) something like this:
db.execSQL("PRAGMA key = '" + mCacheWord.getEncryptionKey() + "';");
db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '';");
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");
Another brief example about this can be seen in this the SQLCipher Users mailing list discussion.
I believe the problem may have to do with the fact that you are using CacheWord, which manages the encryption key separately from SQLCipher. You should verify the format of the string returned from getEncryptionKey() and ensure that it matches the proper format for a raw key in SQLCIpher.
So I've searched and found a lot of info in similar areas, but nothing that quite hits the issue I'm having.
I'm working in a test environment and need to restore from the same SQL database backup (.bak) to many named instances of SQL server. All the sql instances are pre-installed and running.
I played around with different ideas, but a batch file using sqlcmd seems to be the best suited for the job.
So I created a batch file (.bat) that asks for the starting and stopping instance numbers and then should restore from the backup to each SQL named instance incrementing the instance number along the way.
When it runs the sqlcmd appears to work fine. At the end it prints out
RESTORE DATABASE successfully processed X pages in Y seconds
Also the files (.mdf, .ndf, .ldf) are in the directory as expected and then it moves on to the next.
The problem is that when it moves on to the next, the files that were just restored disappear from the directory.
If anyone has any ideas it would certainly be appreciated.
Here's the batch...
ECHO OFF
ECHO Enter starting instance number for restore db
SET /P _IntStart=
ECHO Enter number of last instance for restore db
SET /P _IntStop=
SET /a _IntStop=_IntStop+1
:RestoreDb
If %_IntStart% GEQ %_IntStop% goto:EOF
ECHO Display Instance Number... IntStart = %_IntStart%
sqlcmd -e -s localhost\instance%_IntStart% -d master -U user -P password -Q "Use [master]; RESTORE DATABASE DBName1 FROM DISK = 'C:\DBName1.bak'WITH REPLACE, MOVE 'DBName1' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1.mdf', MOVE 'DBName1_log' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1_log.LDF', MOVE 'ftrow_DBName1Catalog' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1_1.ndf';"
SET /a _IntStart=_IntStart+1
GOTO:RestoreDb
PAUSE
EXIT
=========================================
From SQL Mgmt. Studio I've also tried the below. It works if I comment out the loop and run it each time manually bumping the instance number. It will create separate copies of the db and files. The problem here is SQLCMD doesn't appear to like concatenation in Mgmt. Studio so I can't increment the instance number in the :CONNECT. It ends up trying to connect to localhost\instance$(SCintnum).
Declare #intnum int
Set #intnum = 1
Declare #intstr NVARCHAR(255)
Set #intstr = #intnum
Declare #PathName1 NVARCHAR(255)
Declare #PathName2 NVARCHAR(255)
Declare #PathName3 NVARCHAR(255)
Set #PathName1 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1.mdf'
Set #PathName2 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1_log.LDF'
Set #PathName3 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1_1.ndf'
While #intnum < 51
:SETVAR SCintnum 1
:CONNECT localhost\instance$(SCintnum) -U user -P password
Use [master];
RESTORE DATABASE DBName1 FROM DISK = 'C:\DBName1.bak'
WITH REPLACE,
MOVE 'DBName1' TO #PathName1,
MOVE 'DBName1_log' TO #PathName2,
MOVE 'ftrow_DBName1Catalog' TO #PathName3;
:SETVAR SCintnum $(SCintum)+1
Set #intnum = #intnum+1
Set #intstr = #intnum
Set #PathName1 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1.mdf'
Set #PathName2 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1_log.LDF'
Set #PathName3 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + #intstr + '\MSSQL\DATA\DBName1_1.ndf'
===================================================================
This is an example of what I ended up using in c#.....
///Set SQL Connection
SqlConnection myConnection = new SqlConnection("user id=sa;" +
"password="+ sapassword+";server="+servername+"\\instance"+currentinstancenum+";" +
"Trusted_Connection=yes;" +
"database=master; " +
"connection LifeTime=0; connection Timeout=30");
///Set SQL Command
string thesqlcommand = "USE [master]; RESTORE DATABASE " + dbname + " FROM DISK = '" + backuplocation + "' WITH REPLACE, MOVE '" + dbname + "' TO " + #PathName1 + ", MOVE '" + dbname + "_log' TO " + #PathName2 + ", MOVE 'ftrow_" + dbname + "Catalog' TO " + #PathName3 + ";";
SqlCommand myCommand = new SqlCommand(thesqlcommand, myConnection);
///Set SQL Command TimeOut, open connection, execute command, close command
myCommand.CommandTimeout = 180;
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
It is doing what you asked...
MOVE 'DBName1'
and
MOVE 'DBName1_log'
Ended up creating a little utility in C# to do this. Wish I had started there as it was far simpler. I added an example to the bottom of the original post.
try
{
//Create our connection strings
string sSqlConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + Path.GetDirectoryName(Path.GetDirectoryName(Application.StartupPath)) + "\\ClaimFiles.mdf;Integrated Security=True;User Instance=True";
MessageBox.Show(sSqlConnectionString);
//Execute a query to erase any previous data from our destination table
string sClearSQL = "DELETE FROM PA";
SqlConnection SqlConn = new SqlConnection(sSqlConnectionString);
SqlCommand SqlCmd = new SqlCommand(sClearSQL, SqlConn);
SqlConn.Open();
MessageBox.Show(SqlCmd.ExecuteNonQuery().ToString());
SqlConn.Close();
}
catch (SqlException ex)
{
//handle exception
StringBuilder errorMessages = new StringBuilder();
for (int i = 0; i < ex.Errors.Count; i++)
{
errorMessages.Append("Index #: " + i + "\n" +
"Message: " + ex.Errors[i].Message + "\n" +
"ErrorNumber: " + ex.Errors[i].Number + "\n" +
"Source: " + ex.Errors[i].Source + "\n" +
"Severity Level: " + ex.Errors[i].Class + "\n" +
"Server:" + ex.Errors[i].Server + "\n");
MessageBox.Show(errorMessages.ToString());
}
}
Above is my code in C#, i'm using Microsoft SQL express. the code above is activated upon a click. When i run the code in Visual Studio everything works fine. But when i copy the folder of the project to a different computer(OS: Windows XP) and run the .exe file the program catches a SqlException:
An error has occured while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error 26 - Error Locating Server/Instance Specified)
Can someone help me with this, it would be a great help to solve this problem, because the program must run in a different computer. By the way program's target framework is .NET 3.5
Make sure your server name is correct, e.g., no typo on the name.
Make sure your instance name is correct and there is actually such an instance on your target machine. [Update: Some application
converts \ to . If you are not sure about your application,
please try both Server\Instance and Server\Instance in your
connection string]
Make sure the server machine is reachable, e.g, DNS can be resolve correctly, you are able to ping the server (not always true).
Make sure SQL Browser service is running on the server. If firewall is enabled on the server, you need to put sqlbrowser.exe and/or UDP
port 1434 into exception.
This seems to be a good reference :
http://blogs.msdn.com/b/sql_protocols/archive/2007/05/13/sql-network-interfaces-error-26-error-locating-server-instance-specified.aspx