I am trying to use liquibase to add members to a role, but the SQL is different from SQL Server 2008 to 2012.
SQL Server 2008:
exec sp_addrolemember db_datareader, MYUSER
SQL Server 2012:
ALTER ROLE db_datawriter ADD MEMBER MYUSER
The following SQL when run via liquibase against SQL Server 2012 works correctly, but when ran against SQL Server 2008 it fails and says:
Incorrect syntax near the keyword 'ADD'
Code:
DECLARE #ver nvarchar(50),
#intVer int,
#ver2008 int = 10
SET #ver = CAST(serverproperty('ProductVersion') AS nvarchar)
SET #intVer = CAST(SUBSTRING(#ver, 1, CHARINDEX('.', #ver) - 1) AS int)
IF (#intVer = #ver2008)
exec sp_addrolemember db_datawriter, MYUSER
ELSE
ALTER ROLE db_datawriter ADD MEMBER MYUSER;
I tried separating the versions, putting SQL Server 2008 in one file and 2012 in another and using a 'precondition' at the top of the changelog (outside of a changeset). But there are only 2 OnFail options, HALT, which stops the entire update, or WARN, which just continues the script, both of which do not give me what I need.
I need to be able for the script to figure out which version of SQL Server it is working with and only run that particular liquibase script, whether it be a changeset or changelog.
The compilation of the entire batch will fail if the syntax is unrecognized. You can work around the issue by wrapping the statements in EXECUTE or by using sp_executesql.
IF (#intVer = #ver2008)
EXECUTE(N'exec sp_addrolemember db_datawriter, MYUSER;')
ELSE
EXECUTE(N'ALTER ROLE db_datawriter ADD MEMBER MYUSER;');
Related
I need to copy data from a linked server Oracle table and append to SQL Server table in a regular time interval.
Without using SSIS or any external etl, can this be done by using open query? I have read in forums that the table has to be exported to csv and then imported back again into SQL Server . Is there an alternative as this will be continuous process ?
Certainly. As long as you've configured the Linked Server properly within SQL Server, and your user account has the right permissions in Oracle, getting and sending data between the two is fairly trivial.
Selecting data from Oracle into SQL Server:
IF OBJECT_ID('tempdb..#myTemp') IS NOT NULL DROP TABLE #myTemp
SELECT *
INTO #myTemp
FROM OPENQUERY(MyLinkedServer, 'SELECT col1, col2
FROM OracleTableName
WHERE SomeColumn = ''Human Resources''')
Inserting data from SQL Server into Oracle:
-- note: please make sure you have your columns in the exact same order!
INSERT INTO OPENQUERY(MyLinkedServer, 'SELECT col1
FROM OracleTableName ')
SELECT myPK
FROM AdventureWorks2014.dbo.SomeTable
And you can even drop or recreate a table in Oracle from SQL Server, and run stored procedures.
To create a linked server, I use the below script and these settings:
-- make sure you have Oracle drivers on your SQL Server, and an up-to-date TNSNames.ora file
EXEC master.dbo.sp_addlinkedserver #server = N'MyLinkedServer', #srvproduct=N'Oracle', #provider=N'OraOLEDB.Oracle', #datasrc=N'TNS_NAME_HERE'
-- disable any logins not explicitly mapped
EXEC master.dbo.sp_droplinkedsrvlogin #rmtsrvname = N'MyLinkedServer', #locallogin = NULL
-- login mapping between SQL Server user and their appropriate Oracle account
EXEC master.dbo.sp_addlinkedsrvlogin #rmtsrvname=N'MyLinkedServer',#useself=N'False',#locallogin=N'domain\username',#rmtuser=N'ORACLE_USERNAME',#rmtpassword='ORACLE_PASSWORD'
-- add a mapping for your SQL Agent account if these will run under jobs,
-- and your SQL Engine account if you still get errors on things that are automated,
-- unless those automated jobs are explicitly running under user accounts
Honestly, the hardest part is making sure you get Oracle drivers installed right on the SQL Server. After that, it's very straightforward.
I have two Windows Server 2012 R2 servers in a workgroup, on the first one I have MS SQL Server, the other is used (among other things) as a storage for backups. On the database server both the SQL Server Database Engine and SQL Server Agent run with default virtual accounts - NT Service\MSSQLSERVER and NT Service\SQLSERVERAGENT.
Now, I want to use Ola Hallengren maintenance jobs to backup my MS SQL Server databases. These scripts are wrapped into a SQL Server Agent job but the backup is a t-sql procedure thus executed by the SQL Server Database Engine with NT Service\MSSQLSERVER.
I've created an account on the storage server and a shared folder with access permissions for this account. I'm able to connect the share on the database server with a net use command providing credentials for the created account.
There's a catch: the share is connected for an account which runs the net use command.
If I connect the share with Local System account (which supposed to be for all users) then still NT Service\MSSQLSERVER cannot access it, neither any other account can. Seems like the hack previously proposed on stackoverflow is fixed in Windows Server 2012 R2.
And if I run the net use command as a step in SQL Server Agent job, then it is done with the other virtual account - NT Service\SQLSERVERAGENT - and the backup step fails with "folder not found" error.
So I would like to know a way to create a Windows service account with all the necessary permissions for the SQL Server Database Engine service to be used in a workgroup environment. Or an explanation why it cannot be done.
Ideally it should be a script - Powershell or VBScript.
I tried to run both SQL Server Dabase Engine and SQL Server Agent as Local System and the backup worked like a charm. But I would not consider this as a solution because it's not recommended from a security perspective.
Also I would not consider a solution to run the net use command with xp_cmdshell due to the same security reasons.
Okay, the correct way to get it done is to do the following:
Create a user account on both servers with exactly the same name. This can be done if the user is named .\UserName rather than ServerName\UserName.
Once it is done, you need to sniff permissions of a virtual service account NT Service\MSSQLSERVER. And this can be done with the use of SubInACL utility. This tool is created by Microsoft exactly for the purpose and can be downloaded from official Microsoft Download Center. Or you can skip sniffing the actual permissions and proceed to the next point.
All of the permissions described in the knowledge base article https://msdn.microsoft.com/en-us/library/ms143504.aspx can be set in place for the newly created account with the same SubInACL tool. There are several articles across the Internet on how to use the tool, I used this one - https://redmondmag.com/articles/2008/03/01/dive-deep-with-subinacl.aspx
The last steps will be: launch SQL Server service under the newly created user account and provide access to the shared folder on the other server.
Probably this should go to superuser.com
Will it be possible to use an SSISpackage to do the following:
Create and script via tsql with the login-details,etc. and export it to a script file on disk.
Run the run the script.
Delete the script file again.
Example:
https://www.simple-talk.com/sql/ssis/adding-the-script-task-to-your-ssis-packages/
To create batch file using T-sql:
--Set first day of Week to Monday
--Value First day of the week is
--1 Monday
--2 Tuesday
--3 Wednesday
--4 Thursday
--5 Friday
--6 Saturday
--7 (default, U.S. English) Sunday
SET DATEFIRST 1
Declare #CmdSource varchar(100),
#CmdDestination varchar(100),
#Year varchar(4),
#Week varchar (2),
#Difference int
Set #Difference = 0
Set #Year = Convert(varchar(4), DatePart(Year, GetDate()-#Difference))
Set #Week = Convert(varchar(2), DatePart(week, GetDate()-#Difference))
If #Year = '2010'
BEGIN
Set #Week = #Week - 1
END
SELECT #Week =
CASE Len(#Week)
WHEN 1
THEN '0' + #Week
else #Week
END
Set #CmdSource = 'XCopy "<sourcepath>' + #Year + '\extras text' + #Year + #Week + '.bak" '
Set #CmdDestination = '"<Destination path>" /Y'
SELECT #CmdSource + #CmdDestination as Batchfile
We opted for creating the file at a set time. We then setup a separate windows scheduled task to run independently from SQL at a set time after the creation. Running with SSIS at that time 2010 was unpredictable. There is only one very long destination column (length 200, up to you how long.)
IMHO, your best bet still is to run net use \\remotehost\folder password /user:remotehost\username in xp_cmdshell.
You only need to run it once and then can close off xp_cmdshell again if you don't like it; it's not like changing that option requires a reboot =)
For that I'd suggest to put this into 'startup' procedure. You can even add WITH RECOMPILE if you're afraid someone will sp_helptext it to find the pwd of that login. Then again, people might freak out when finding a startup proc that's encrypted =)
USE master
GO
CREATE PROCEDURE sp_net_use_that_other_server
AS
-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1;
-- To update the currently configured value for advanced options.
RECONFIGURE;
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1;
-- To update the currently configured value for this feature.
RECONFIGURE;
-- you might want to fetch this dynamically from the database somewhere, or simply leave it hardcoded here...
EXEC master..xp_cmdshell 'net use \\remotehost\folder password /user:remotehost\username'
-- To disable the feature.
EXEC sp_configure 'xp_cmdshell', 0;
-- To update the currently configured value for this feature.
RECONFIGURE;
Return
GO
-- set this up as a startup procedure
EXEC sp_procoption #ProcName = 'sp_net_use_that_other_server'
, #OptionName = 'startup'
, #OptionValue = 'on';
GO
After that, the database engine should be able to BACKUP DATABASE... to that share.
I am trying to create an assembly in SQL Server 2008 R2. I am using this below code to create the assembly.
CREATE ASSEMBLY [WRQ.Verastream.HostIntegrator]
AUTHORIZATION [dbo]
FROM 'D;\.....\WRQ.Verastream.HostIntegrator.dll'
WITH PERMISSION_SET = UNSAFE GO
But I am getting this error.
Msg 6586, Level 16, State 1, Line 1
Assembly 'WRQ.Verastream.HostIntegrator' could not be installed because existing policy would keep it from being used.
According to this article by Microsoft, Only members of the sysadmin fixed server role can create and alter UNSAFE assemblies. You will need to add your current login to the sysadmin fixed server role.
I don't have my management studio available at this time, but I believe this will work:
USE YOURDATABASENAME
GO
EXEC sp_addsrvrolemember 'YOURUSERNAME', 'sysadmin';
Run the following command:
select * from sys.fn_my_permissions(NULL, 'SERVER')
where permission_name like '%ASSEMBLY%'
You're looking to see if you have either "external access assembly" or "unsafe assembly" (you'll likely need the latter). Also check to make sure that CLR is enabled at the server level with the following:
select value_in_use from sys.configurations where name = 'clr enabled'
If that doesn't return 1, CLR flat out won't run.
I am attempting to recreate a SQL Server Compact database from a script. I started off creating it like this:
CREATE DATABASE [MyDatabase]
GO
and that seemed to work. The next commands in the script are these:
ALTER DATABASE [MyDatabase] SET ANSI_NULL_DEFAULT OFF
GO
and about two dozen similar commands. I have tried a representative sample of these and they all return the error:
Major Error 0x80040E14, Minor Error 25501
ALTER DATABASE [MyDatabase] SET ANSI_NULLS OFF
There was an error parsing the query. [ Token line number = 1,Token line offset = 7,Token in error = DATABASE ]
Does anyone know what the matter is?
I'm using Microsoft SQL Server Management Studio 2008 R2 on Windows XP.
If you check here - http://msdn.microsoft.com/en-US/library/ms174454(v=sql.90).aspx, I don't think you can do alter database in SQL Server CE.
I've been having a very difficult time trying to read a table on one server and writing to another existing table on my hard drive (local... created using SQL Server Express).
Here's my code:
insert into [DPS-ABC1DE2\SQLEXPRESS].my_LOCAL_DATABASE.dbo.SHIPMENTS
select
CUST_NUMBER,
SHIPMENT_ID,
SHIP_DATE,
MODE_CODE,
MILES,
WEIGHT,
AMOUNT_PAID
from SHARED_DATABASE.dbo.SHIPMENTS
where datepart(year,SHIP_DATE)= 2012 and datepart(month,SHIP_DATE) = 1
I get the following error message when I run this:
Msg 7202, Level 11, State 2, Line 7
Could not find server 'DPS-ABC1DE2\SQLEXPRESS' in sys.servers. Verify that the correct
server name was specified. If necessary, execute the stored procedure
sp_addlinkedserver to add the server to sys.servers.
So I've tried using
EXEC sp_addlinkedserver [DPS-ABC1DE2\SQLEXPRESS]
but I get this error:
"Msg 15247, Level 16, State 1, Procedure sp_MSaddserver_internal, Line 29
User does not have permission to perform this action."
I'm a rookie SQL programmer, so I've had to research this extensively but with no success. Any help would be appreciated!
sp_addlinkedserver execute permissions default to members of the sysadmin and setupadmin fixed server roles. Check out this link on how to sort it out on sql server 2005.
Once you get rid of that issue you could use the following to link and login to the other server.
--add the linked server and then login
EXEC sp_addlinkedserver 'DPS-ABC1DE2\SQLEXPRESS',N'SQL Server';
EXEC sp_addlinkedsrvlogin #rmtsrvname='DPS-ABC1DE2\SQLEXPRESS',
#useself='false',
#rmtuser='login_username',
#rmtpassword='login_password'
--do your job here
Insert into [DPS-ABC1DE2\SQLEXPRESS].my_LOCAL_DATABASE.dbo.SHIPMENTS
Select...
--drop the linked server login and then drop the server
EXEC sp_droplinkedsrvlogin 'DPS-ABC1DE2\SQLEXPRESS', NULL
EXEC sp_dropserver 'DPS-ABC1DE2\SQLEXPRESS', NULL;
Hope this helps...