Microsoft SQL server: copy table from linked server to current database using a stored procedure - sql

I am using Microsoft SQL server. the following code works if run from a QUERY:
SELECT *
INTO mydatabase.dbo.atable
FROM linkedserver.sandbox.dbo.atable
but it does not if inserted into a stored procedure:
SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE dataMigration
AS BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT *
INTO mydatabase.dbo.atable
FROM linkedserver.sandbox.dbo.atable
END
GO
Command(s) completes successfully but no table is created into mydatabase. Sorry for the trivial question. I had a look at similar issues but i did not find a case similar to mine.
Thank you for your help.

You have to execute the stored Procedure after you run the code to alter it.
try running:
exec dataMigration

Right clickOption Image the store procedure and click "Execute Store procedure"

Related

Stored procedure with temporary tables, Entity Framework updating the stored procedure not working - SET FMTONLY OFF

I have a stored procedure which has multiple temporary tables, when I tried importing it in Entity Framework it didn't create the complex type and I get this error:
The selected stored procedure or function returns no columns
When I googled, I found adding this piece of code SET FMTONLY OFF in the stored procedure will create the complex type in my EDMX. I was able to do it.
Everything works well in Entity Framework now after adding SET FMTONLY OFF.
Now my question is, is there a security threat by adding this piece of code to my stored procedure which contains multiple temp tables ?
Thank you.
You don't want to just SET FMTONLY OFF, as that could have unintended consequences, but you could return an empty result set of the right shape, then turn FMTONLY OFF and RETURN at the beginning of your stored procedure.
eg
if 1=0 --this will only run in FMTONLY is ON
begin
select cast(1 as decimal(12,0) a, cast('x' as nvarchar(20)) b -- . . .
set fmtonly off
return;
end
Since FMTONLY ignores control flow statements it will run the code in the begin/end. The client will get an empty resultset, then the procedure exists. You have to turn off FMTONLY or else the return will not be executed, and you will get an error with your temp tables later.
When this stored procedure is run without FMTONLY the if 1=0 will be evaluated, and that block skipped.
However switching out the stored procedure for one without temp tables when you update the EF model is a valid alternative.

I've generated an sql file full of inserts but can't find any documentation of executing this script from a stored procedure

I'm creating a stored procedure that will delete all the data in my database and then insert the data from my sql file. The reason I am using the delete and insert instead of a restore is because a restore requires that no one is connected to the database where as deleting and inserting allows people to still be connected.
Stored Procedure:
CREATE PROCEDURE DropAndRestore
-- Add the parameters for the stored procedure here
#filepath nvarchar(200)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
Exec sp_MSFOREACHTABLE 'delete from ?
RESTORE DATABASE [landofbeds] -- These lines are what needs to be replaced
FROM DISK = #FilePath --
END
GO
The reason I am using the delete and insert instead of a restore is
because a restore requires that no one is connected to the database
where as deleting and inserting allows people to still be connected
If all you need is minimum downtime you can restore your database in db_copy. Then drop your db and rename db_copy to db.
Yes you should disconnect all the users to be able to drop your db, but it will take minimum time, while if you delete your data the table will still be unavailable for the whole duration of the delete, and as delete is always fully logged your users will wait.
To launch your script you can use xp_cmdshell that calls sqlcmd with -i but it's not a good idea. You have no control on your script execution and if something goes wrong you will have even more downtime for your users.
Does your tables have FK defined?
Exec sp_MSFOREACHTABLE 'delete from ?
will try to delete everything in order it decides and you may end up with errors when you try to delete rows that are referenced in other tables.
To execute your sql file from Stored procedure .. you can use xp_cmdshell. See steps below
First Create a Batch File (C:\testApps\test.bat) and execute your sql file from there..
e.g.
osql -S TestSQlServer -E -I C:\testApps\test.sql > C:\testApps\tlog.txt
Then add this line to your Calling Stored procedure
exec xp_cmdshell 'C:\testApps\test.bat'
Execute your procedure
**Please note you will need to enable xp_cmdshell
You can use bulk insert like this:
BULK INSERT landofbeds.dbo.SalesOrderDetail
FROM '\\computer\share\folder\neworders.txt'

Can't create stored procedure with reference to table in other database

I have some databases on Azure SQL v12. One is named GM_STAGE and one STRAT_CMS.
I am trying to add this stored procedure to STRAT_CMS:
CREATE PROCEDURE [dbo].[SP_GM_STAGE_FILE_LOAD_STS_GET]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT *
FROM [GM_STAGE].[dbo].[FILE_LOAD_STATUS]
END
I am getting this error which I don't understand because the database clearly exists.
Reference to database and/or server name in 'GM_STAGE.dbo.FILE_LOAD_STATUS' is not supported in this version of SQL Server.
Why can't I create this stored procedure?
Cross database queries are supported in Azure SQL v12. Make sure that both databases you are using are up to date.
https://azure.microsoft.com/en-us/blog/querying-remote-databases-in-azure-sql-db/

Why is this statement included in the stored procedure definition?

I got nailed today by a typo, its a simple typo when I defined a script to create a stored procedure under Sql Server 2005, I forgot a GO statement in between the END statement and the GRANT statement, this lead to the GRANT statement being included in the stored procedure definition and running at the end of the stored procedure (verified with SQL Profiler).
Here is the code:
USE [TestGround]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[FooProc]
AS
BEGIN
SELECT * FROM dbo.Foo
END
-- a GO statement is missing here..
GRANT EXECUTE ON [dbo].[Foo] TO dbo
I understand that GO signifies the end of a batch, but I was surprised to see that the GRANT statement was included in the stored procedure, I've never forgotten the GO statement before so haven't seen this issue.
Could someone please explain to me why this happens?
You can leave out the BEGIN / END pair: the definition doesn't end at END. It continues until the end of the file or a GO, whichever comes first.

create stored procedure if doesn't exist in sql server

Oracle does "create or replace" statements. Sql server does not seem to - if you are scripting out from Enterprise Manager, it instead suggests "drop and create" instead. Drop and create is undesirable in any situation where you've done grants on the stored procedure, because it tosses out any grants your database administration team has done. You really need "create or replace" to help with separation of conerns between developers and administrators.
What I've been doing recently is this:
use [myDatabase]
go
create procedure myProcedure as
begin
print 'placeholder'
end
go
alter procedure myProcedure as
begin
-- real sproc code here
end
go
This does what I want. If the procedure doesn't exist, create it then alter in the correct code. If the procedure does exist, the create fails and the alter updates the code with the new code.
It creates a different problem for the administrators, because the create throws a misleading error if the stored procedure already exists. Misleading, of course, in the fact that you shouldn't see red error text when the desired outcome has occured.
Does anyone have a way to suppress the red text? Everything I've tried leads to a 'CREATE/ALTER PROCEDURE must be the first statement in a query batch' error in some way or another.
This will work and keep the permissions intact:
use [myDatabase]
go
if object_id('dbo.myProcedure', 'p') is null
exec ('create procedure myProcedure as select 1')
go
alter procedure myProcedure as
SET NOCOUNT ON
-- real sproc code here. you don't really need BEGIN-END
go
Like this:
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[myProcedure]')
AND type in (N'P', N'PC'))
BEGIN
EXEC('
create procedure myProcedure as
begin
print ''placeholder''
end
')
END
EXEC('
alter procedure myProcedure as
begin
-- real sproc code here
end
')
NOTES:
remember to double up your quotes in the dynamic SQL strings.
I have indented it for readability, but that will also add the extra indent spaces to your actual procedures listings. If you don't wnat that, then just reduce the indentation level on the dynamic SQL text.
Finally the day is here where SQL Server has implemented an equivalent to Create or Replace. Their equivalent is "Create or Alter". This is available as of SQL Server 2016 SP1. Example usage:
use [myDatabase]
go
Create or Alter procedure myProcedure as
begin
-- procedure code here
end
go