I need to integrate a few lines of code into my application , which allow me to copy a database from one MSSQL server to another MSSQL server, the code header should be like this
procedure MoveDataBase (OldServername : String; newServerName : String ; Databasename : String);
begin
end;
Any short code and fast working Idea ?
Copy a Database using MS Explorer is no option
The easiest (and maybe also the dumbest) way of transfering a database from one server to the other is to:
1. detach the database on the source server using sp_detach_db
2. copy the physical MDF file to the destination server. You may copy the LDF as well, but imho it is not necessary.
3. attach the database on the destination server using sp_attach_db
You might also replace #1 and #3 by a BACKUP/RESTORE as stated earlier. In any case (I am repeating the commments), you'd need a bit more than just server name and database, i.e. login credentials, for example.
Related
I would use the power of Firebird Events with delphi application with TIBEvents component.
The problem is the firewall, not every time have the correct role and when I try to register the events the application stops responding and I must wait...
How can I do?
I also try to call register function in a separated thread but with the same result.
function RegisterEvents(data : Pointer) : Integer;
begin
with Form1 do begin
DBOspitiEvent.Registered := true;
end;
end; //<-- AFTER THIS, APPLICATION IS BLOCKED (for a while)
procedure TForm1.Button2Click(Sender: TObject);
var
ThreadId : Cardinal;
ThreadHandle : Integer;
begin
ThreadHandle := BeginThread(nil,0,#RegisterEvents,nil,0,ThreadId);
if ThreadHandle = 0
then ShowMessage('Error');
end;
For events, a client needs to establish a separate connection, and by default Firebird uses a random port for this. In combination with firewalls, this leads to problems because the port is - for example - not allowed.
You can configure Firebird to use a fixed port, by editing firebird.conf and setting the RemoteAuxPort to a fixed value (eg 3051), and restarting Firebird. You can then configure your firewall to allow this port.
See also How to configure events with firewall?
We had many problems with TIBEvent components since XP SP3 too.
Here is what works perfectly fine for us since than, even with newest Win10 updates:
We use UIB for receiving events. TUIBEvents component. (You may keep IBX for everything else... but UIB is better and faster and FB3.0 compatible.)
Do not execute any long-lasting code inside OnEvent procedure, but rather set multithread-safe variables to mark, what event you received (last time)
Deal with those variable inside each window locally. (For example: running a timer that checks and compares last-event-time with local last-refresh-time.)
If you are running SQL queries in a separate Thread, always create new database + transaction component, DO NOT USE the one from the main thread!
Open 3050 and 3051 TCP ports on Firewall!
We also add "fbserver.exe" file to Firewall exception and to Defender exception.
Set fixed ports in "firebird.conf" file: RemoteServicePort=3050 and RemoteAuxPort=3051
You may create a single FirstInstallScrip.bat file to do all these firewall changes and copies a pre-edited .conf file to FB's directory, overwriting the original one.
And YES, you can create these simple text files easily from Delphi and run it from there. Or notify the user if not ran yet. (You can read the original config file and compare those settings.)
#ECHO program in
#NETSH advfirewall firewall add rule name="FirebirdSQL szerver" program="%programfiles%\Firebird\Firebird_2_5\bin\fbserver.exe" profile=public,private,domain dir=in action=allow edge=yes description="FirebirdSQL Database engine"
#ECHO program out
#NETSH advfirewall firewall add rule name="FirebirdSQL szerver" program="%programfiles%\Firebird\Firebird_2_5\bin\fbserver.exe" profile=public,private,domain dir=out action=allow description="FirebirdSQL Database engine"
#ECHO ports in
#NETSH advfirewall firewall add rule name="FirebirdSQL portok" localport=3050-3051 protocol=tcp profile=public,private,domain dir=in action=allow edge=yes description="FirebirdSQL Database engine ports"
#ECHO ports out
#NETSH advfirewall firewall add rule name="FirebirdSQL portok" localport=3050-3051 protocol=tcp profile=public,private,domain dir=out action=allow description="FirebirdSQL Database engine ports"
#pause
As #Victoria suggested: use better business logic!
You may store your data (red from DB) in PC's memory and show it from there.
Create triggers inside your FB database self-updating the last modification.
Do not delete rows, just mark them as "deleted".
check only "what changed" SELECT * from "Customers" c where c.MODIFIED > '2019...' and compare with data already downloaded before, to reduce SQL load.
use separate, short-time transaction to write data into DB.
I have a stored procedure created in MySQL DB. This database is accessed as linked server through Microsoft SQL Server 2012 using Microsoft SQL Server Management Studio. The provider selected while creating linked server is "Microsoft OLE DB Provider for ODBC Drivers".
When I run following as text from Report builder 3.0 it runs fine and fetch data.
EXEC('CALL storedProcedureName(''string1'', ''string2'', ''string3'')') AT LinkedServerName;
But when I try to replace string1, string2, string3 with parameter name parameter1, parameter2, parameter3 as:
EXEC('CALL storedProcedureName(#parameter1, #parameter2, #parameter3)') AT LinkedServerName;
I get error:
Could not execute statement on remote server 'LinkedServerName'.
(Microsoft SQL Server, Error: 7215)
And when I try:
EXEC('CALL storedProcedureName('#parameter1', '#parameter2', '#parameter3')') AT LinkedServerName;
I get the prompt to enter values for parameter1, parameter2, parameter3. But when I enter the values and click ok, I get error:
Incorrect syntax near '#parameter1'. (Microsoft SQL Server, Error: 102)
Question: Am I missing something in syntax or is this a bug?
The linked server has:
"RPC" and "RPC out" set to True.
And the OLEDB provider has:
Enabled allow inprocess
Enabled dynamic parameter
I believe you have to call it like the below. So params become strings wrapped in single quotes:
EXEC('CALL storedProcedureName('''+#parameter1+''', '''+#parameter2+''', '''+#parameter3+''')') AT LinkedServerName;
I know this is an older question but the accepted answer is open to SQL Injection and I think it's important to offer a more secure method.
You really want to use a parameterized query
EXEC('CALL storedProcedureName(?,?,?)',#parameter1, #parameter2, #parameter3) AT LinkedServerName;
I know this works for oracle and it should work for MySql as well.
I'm doing an application to show data from a mdb file, it works on a copy of the db, but, when I try to use the one that updates the data, it tells me that the database is already in use.
I use an odbc connection with this configuration:
Driver = 'Microsoft Access Driver (*.mdb)'
Params.Strings = (
'DBQ=Data.mdb'
'Locale Identifier=1031'
'ExtendedAnsiSQL=1'
'CHARSET=ansi'
)
Is there any way to read this mdb file, the copy is not an option, I need to read every 10 seconds and the file is ... more than 100MB.
Than you very much.
Please do me a favor, I want to maintain all the stored procedures in one database, let's say SP_Dbase.
I plan this scheme, user application determine dbase_xyz and will go to SP_stored_procedure in SP_Dbase and then retrieve or edit data of dbase_xyz.
Since command Use dbasename does not work in a stored procedure, I have big difficulty.
I don't intend to write down all the procedure as an execute command as follows :
Set #cmd = 'select .... from ' + #DB + '.dbo.tablename'
EXEC(#cmd)
Anyone could help me ?
Note: All databases have same structure and exist in one SQL Server 2008 R2 instance.
Thanks
Microsoft has recently broken our longtime (and officially recommended by them) code to read the version of Excel and its current omacro security level.
What used to work:
// Get the program associated with workbooks, e.g. "C:\Program Files\...\Excel.exe"
SHELLAPI.FindExecutable( 'OurWorkbook.xls', ...)
// Get the version of the .exe (from it's Properties...)
WINDOWS.GetFileVersionInfo()
// Use the version number to access the registry to determine the security level
// '...\software\microsoft\Office\' + VersionNumber + '.0\Excel\Security'
(I was always amused that the security level was for years in an insecure registry entry...)
In Office 2010, .xls files are now associated with "“Microsoft Application Virtualization DDE Launcher," or sftdde.exe. The version number of this exe is obviously not the version of Excel.
My question:
Other than actually launching Excel and querying it for version and security level (using OLE CreateOLEObject('Excel.Application')), is there a cleaner, faster, or more reliable way to do this that would work with all versions starting with Excel 2003?
Use
function GetExcelPath: string;
begin
result := '';
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', false) then
result := ReadString('Path') + 'excel.exe';
finally
Free;
end;
end;
to get the full file name of the excel.exe file. Then use GetFileVersionInfo as usual.
As far as I know, this approach will always work.
using OLE CreateOLEObject('Excel.Application'))
you can get installed Excel versions by using the same registry place, that this function uses.
Basically you have to clone a large part of that function registry code.
You can spy on that function call by tools like Microsoft Process Monitor too see exactly how does Windows look for installed Excel - and then to do it exactly the same way.
You have to open registry at HKEY_CLASSES_ROOT\ and enumerate all the branches, whose name starts with "Excel.Application."
For example at this my workstation I only have Excel 2013 installed, and that corresponds to HKEY_CLASSES_ROOT\Excel.Application.15
But on my another workstation I have Excel 2003 and Excel 2010 installed, testing different XLSX implementations in those two, so I have two registry keys.
HKEY_CLASSES_ROOT\Excel.Application.12
HKEY_CLASSES_ROOT\Excel.Application.14
So, you have to enumerate all those branches with that name, dot, and number.
Note: the key HKEY_CLASSES_ROOT\Excel.Application\CurVer would have name of "default" Excel, but what "default" means is ambiguous when several Excels are installed. You may take that default value, if you do not care, or you may decide upon your own idea what to choose, like if you want the maximum Excel version or minimum or something.
Then when for every specific excel branch you should read the default key of its CLSID sub-branch.
Like HKEY_CLASSES_ROOT\Excel.Application.15\CLSID has nil-named key equal to
{00024500-0000-0000-C000-000000000046} - fetch that index to string variable.
Then do a second search - go into a branch named like HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer ( use the fetched index )
If that branch exists - fetch the nil-named "default key" value to get something like C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation
The last result is the command line. It starts with a filename (non-quoted in this example, but may be in-quotes) and is followed by optional command line.
You do not need command line, so you have to extract initial commanlind, quoted or not.
Then you have to check if such an exe file exists. If it does - you may launch it, if not - check the registry for other Excel versions.