I have A SQLSERVER Database, I want to Delete all tables except some tables
i use use this script
EXEC sp_MSforeachtable 'IF OBJECT_ID(''?'') NOT IN (
ISNULL(OBJECT_ID(''[dbo].[T1]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T2]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T3]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T4]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T5]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T6]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T7]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T8]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T9]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T10]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T11]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T12]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T13]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T14]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T15]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T16]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T17]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T18]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T19]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T20]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T21]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T22]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T23]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T24]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T25]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T26]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T27]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T28]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T29]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T30]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T31]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T32]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T33]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T34]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T35]''),0)
)
DELETE FROM ?'
the sqlserver return this error message "Msg 102, Level 15, State 1, Line 22
Incorrect syntax near 'ISN'."
I think the problem may be about the number of tables which is excepted
Try to do it another way:
DECLARE #command nvarchar(max);
--Remove spaces in front of ,ISNULL
SELECT #command = N'IF OBJECT_ID(''?'') NOT IN (
ISNULL(OBJECT_ID(''[dbo].[T1]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T2]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T3]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T4]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T5]''),0)
...
,ISNULL(OBJECT_ID(''[dbo].[TN]''),0)
)
DELETE FROM ?';
EXEC sp_MSforeachtable #command;
NOTE: This SP works only with nvarchar(2000) in first command (source).
It is the first command to be executed by this Stored Procedure and the data type is nvarchar(2000).
EXEC sp_MSforeachtable N'IF OBJECT_ID(''?'') NOT IN (ISNULL(OBJECT_ID(''[dbo].[T1]''),0),ISNULL(OBJECT_ID(''[dbo].[T2]''),0),ISNULL(OBJECT_ID(''[dbo].[T3]''),0),ISNULL(OBJECT_ID(''[dbo].[T4]''),0),ISNULL(OBJECT_ID(''[dbo].[T5]''),0),ISNULL(OBJECT_ID(''[dbo].[T6]''),0),ISNULL(OBJECT_ID(''[dbo].[T7]''),0),ISNULL(OBJECT_ID(''[dbo].[T8]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T9]''),0),ISNULL(OBJECT_ID(''[dbo].[T10]''),0),ISNULL(OBJECT_ID(''[dbo].[T11]''),0),ISNULL(OBJECT_ID(''[dbo].[T12]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T13]''),0) ,ISNULL(OBJECT_ID(''[dbo].[T14]''),0),ISNULL(OBJECT_ID(''[dbo].[T15]''),0),ISNULL(OBJECT_ID(''[dbo].[T16]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T17]''),0),ISNULL(OBJECT_ID(''[dbo].[T18]''),0),ISNULL(OBJECT_ID(''[dbo].[T19]''),0),ISNULL(OBJECT_ID(''[dbo].[T20]''),0),ISNULL(OBJECT_ID(''[dbo].[T21]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T22]''),0),ISNULL(OBJECT_ID(''[dbo].[T23]''),0),ISNULL(OBJECT_ID(''[dbo].[T24]''),0),ISNULL(OBJECT_ID(''[dbo].[T25]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T26]''),0),ISNULL(OBJECT_ID(''[dbo].[T27]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T28]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T29]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T30]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T31]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T32]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T33]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T34]''),0)
,ISNULL(OBJECT_ID(''[dbo].[T35]''),0)
)
DELETE FROM ?'
The issue is that sp_msforeachtable has first parameter of length 2000 to which your query is passed. Since your query is of length more than that, full text of it is not passed to proc. That's why the error. Shorten the length of query by removing some line breaks. Try my query its working
Related
This is my code
DECLARE #stringvariable nvarchar(200) = 'Hello';
DECLARE #sql nvarchar(2000) = SELECT * INTO ##global FROM OPENQUERY(DB1, ''EXEC GETCASE ''' + #stringvariable + ''''')'
Printing #sql returns a correctly formatted query, however SQL Server doesn't like #stringvariable and returns an error
Msg 102, Level 15, State 1, Line 11
Incorrect syntax near 'Hello'.
Here is what the outputted query looks like
SELECT * INTO ##global FROM OPENQUERY(DB1, 'EXEC GETCASE 'Hello'')
How can I avoid this error? It seems like because my stored procedure takes a string parameter, it's throwing off the query. I've read that OPENQUERY does not support variables, but I've parameter the variable so it should work?
Appreciate your help!
The stored procedure exists in a database and a schema. You need to supply those. Supposing database db_name and schema schema_name:
DECLARE #stringvariable nvarchar(200) = 'Hello';
SET #stringvariable=REPLACE(#stringvariable,'''',''''''''''); -- doubly doubled single quotes for the dynamic statement
DECLARE #sql nvarchar(2000) = 'SELECT * INTO ##global FROM OPENQUERY(DB1, ''SET FMTONLY OFF;EXEC db_name.schema_name.GETCASE ''''' + #stringvariable + ''''''')';
I've also made sure single quotes are properly escaped in the #stringvariable.
It's also likely you need to start the query with SET FMTONLY OFF; so I've added that.
Update: To test this I created following simple procedure on a linked server local_server in database TEST_TT
CREATE PROCEDURE [dbo].[tst]
#i VARCHAR(128)
AS
SELECT #i AS field;
I then ran the following:
DECLARE #var VARCHAR(128)='TT.';
SET #var=REPLACE(#var,'''',''''''''''); -- doubly doubled single quotes for the dynamic statement
DECLARE #stmt VARCHAR(4000)='SELECT * INTO ##tt FROM OPENQUERY(local_server,''SET FMTONLY OFF;EXEC TEST_TT.dbo.tst '''''+#var+''''''');';
EXEC (#stmt);
SELECT * FROM ##tt;
DROP TABLE ##tt;
And I received the results. I count 7 (!!) single quotes at the end of the query... yuck! Updated original part with the same number of quotes.
I have one question. I was creating below procedure temporary.
When I Execute it in below format it works fine:
CREATE PROCEDURE Get_TableList_By_Name
#Proc_Name VARCHAR(255)
AS
BEGIN
SELECT * FROM sys.tables WHERE name LIKE '%' + #Proc_Name + '%'
END
GO
EXEC Get_TableList_By_Name 'norway'
GO
DROP PROCEDURE Get_TableList_By_Name
GO
But when I execute same SQL in below format it giving error saying: "Incorrect syntax near 'GO'."
CREATE PROCEDURE Get_TableList_By_Name #Proc_Name VARCHAR(255) AS BEGIN SELECT * FROM sys.tables WHERE name LIKE '%' + #Proc_Name + '%' END GO EXEC Get_TableList_By_Name 'norway' GO DROP PROCEDURE Get_TableList_By_Name GO
CREATE PROCEDURE Get_TableList_By_Name #Proc_Name VARCHAR(255) AS BEGIN SELECT * FROM sys.tables WHERE name LIKE '%' + #Proc_Name + '%' END GO 1 EXEC Get_TableList_By_Name 'norway' GO 1 DROP PROCEDURE Get_TableList_By_Name GO 1
How to write same SQL with GO statement in single line?
Is it possible? If not then Why?
Thanks,
Vishal
From GO (Transact-SQL)
A Transact-SQL statement cannot occupy the same line as a GO command.
However, the line can contain comments.
So Go needs to be on its own line, except for comments.
'GO' is not a SQL command. It is a batch terminator recognized by tools
like Query Analyzer, SSMS, SQLCMD, etc. These tools generally require the
GO to be on a separate line and send the preceding SQL statements as a batch
to SQL Server when the GO is encountered
GO Statement must be written in new line as it is not T-SQL command.
T-SQL statement can not occupy the same line as GO. GO statement can contain comments.
You can execute this:
EXEC SP_COMMAND 1,2;
EXEC SP_COMMAND 2,2;
EXEC SP_COMMAND 3,2;
Set EXEC Bebore sp and ';' for end statement
then
select all code (SSMS) and press f5 o exec all you code by other thecnic.
I have to move a table into other table using a stored procedure by passing the table names as parameters.
Syntax is:
alter procedure [dbo].[moving]
(
#to_table varchar(50),
#from_table varchar(50)
)
as
begin
EXEC('Select * into '+#to_table+'from '+#from_table)
end
while executing by.
exec moving newtable,hello
It is giving an error:
Incorrect syntax near 'hello'
pls anyone give solution for this
Try:
exec moving 'newtable','hello'
It also looks like you are going to need to fix your SP. You will need a space before from:
EXEC('Select * into '+#to_table+' from '+#from_table)
Read EXECUTE syntax and try,
EXEC moving 'newtable','hello'
SELECT ... INTO needs to create table, if table exists use INSERT INTO ... SELECT ..FROM
AND
in your case you need to run SP in such a way:
EXEC dbo.moving 'table1', 'table2'
BUT
EXEC('Select * into '+#to_table+' from '+#from_table)
will not work, you need to rewrite it with variable:
declare #sql nvarchar(max)
SET #sql = N'Select * into ['+#to_table+N'] from ['+#from_table+N']'
EXEC(#sql)
BUT
you also need to worry of sql injections and complex table names AT LEAST, so - for complex table names I already framed your tables with square braces, and you need to do something to prevent sql injections.
And once more - SELECT...INTO works only if you creating new table with name from #to_table parameter
add an extra space after single quote and FROM
EXEC('Select * into ' + #to_table + ' from ' + #from_table)
I have SQL Server 2008 with a linked Sybase server and I am trying to execute a stored procedure on the Sybase server using OPENQUERY. If I have a stored proc that doesn't take parameters it succeeds fine. If I have a stored proc with parameters it fails. I even tried a very basic stored proc that only took an int an that still failed. Below is the syntax I am using:
select * from
OPENQUERY([LINKSERVER],'exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
Msg 7357, Level 16, State 2, Line 3
Cannot process the object "exec database.user.my_stored_proc 'AT','XXXX%','1111',1". The OLE DB provider "ASEOLEDB" for linked server "LINKSERVER" indicates that either the object has no columns or the current user does not have permissions on that object.
As the proc will execute just fine without parameters, I don't think it is a permission issue.
This worked for me,
SELECT * FROM OPENQUERY(LOCALSERVER, 'SET FMTONLY OFF EXEC snr.dbo.GetAllSignals #controlRunId = 25, #experimentRunId = 26')
I was creating temporary tables, and that's why i got access denied
Here is more info http://www.sommarskog.se/share_data.html#OPENQUERY
I create a sp that doesn't return any value and it doesn't work.
Your SP in mysql have to return a value!
for example I do this in "mysql":
CREATE DEFINER=`root`#`localhost` PROCEDURE `MyPro`(IN `Name` VARCHAR(50), IN `Id` INT, OUT `Result` INT)
MODIFIES SQL DATA
BEGIN
DECLARE Result INT;
SET Result = 0;
INSERT into MyTable (Id,Name) VALUES(Id,Name);
SELECT Result;
END
That "Id" and "Name" is input parameter and "Result" is output parameter
and create linked server in SQL SERVER and call it like this:
select * from openquery
(
Test,'call mydb.MyPro(''Name'',''16'', #P0);'
)
It works for me :D
Linked Servers and OPENQUERY, Gems to MS SQL Server...that are wolves in sheep clothing. I've found the following solutions to work when dealing with parameters
If the SP is basically just SELECT statements, the move the same to a VIEW and just pass SQL statements via OPENQUERY.
Build the OPENQUERY as a string and then use execute_sql.
You could also see if it works to precede exec with SET FMTONLY ON:
OPENQUERY([LINKSERVER],'SET FMTONLY ON; exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')
If you try this and it works, you should probably Google FMTONLY+OPENQUERY to get an idea of what it means.
Try this,
SELECT * FROM OPENQUERY(linked_server_name, 'SELECT postgres_procedure_name (parameters)');
I experienced a very similar issue, but my SP wasn't taking any parameters.
I tried experimenting with altering the query sent through the openquery to include 'SET NOCOUNT ON' and 'SET FMTONLY OFF' but this had no difference.
The only solution that worked for my stored procedure was dropping the existing version, and altering the code to specifically 'SET NOCOUNT ON'
After doing this I was able to successfully run my stored proc through my linked server connection.
First of all you have to add hard code text fields then you have to
replace it by your parameters value like FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType
DECLARE #startdate varchar(255) = '2019-12-17'
DECLARE #enddate varchar(255) = '2019-12-17'
Set #SQL = 'SELECT * FROM OPENQUERY(' + quotename(#LinkedServer) + ',' + '''' +
'SET FMTONLY OFF; exec [TAP].[dbo].[GetAttendanceList] ' + 'FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType,1'')'
You have to replace your parameters values shown below
set #SQL=REPLACE(#SQL,'FromDate',+''''+''''+#startdate+''''+'''')
set #SQL=REPLACE(#SQL,'TillDate',+''''+''''+#enddate+''''+'''')
set #SQL=REPLACE(#SQL,'CompCode',+''''+''''+#CompCode+''''+'''')
set #SQL=REPLACE(#SQL,'AtnType',+''''+''''+''''+'''')
if #EmpID is Null
begin
set #SQL=REPLACE(#SQL,'EmpID','null')
end
if #DeptID is Null
begin
set #SQL=REPLACE(#SQL,'DeptID','null')
end
if #DesgId is Null
begin
set #SQL=REPLACE(#SQL,'DesgId','null')
end
if #LocationID is Null
begin
set #SQL=REPLACE(#SQL,'LocationID','null')
end
print #SQL
exec ( #SQL)
I want to create a Stored procedure and Job in Ms SQL server that would delete all tables in a schema that are more than a weeks old.
i create backups every single day and i want to automate the process by scheduling a job to delete any backups(SQL Tables) that are older than a week.
Your help would be greatly appreciated.
You can use the sys.objects keyword within SQL Server to accomplish this.
The query would be something like:
USE [Your_Database_Name];
GO
SELECT name AS object_name
,SCHEMA_NAME(schema_id) AS schema_name
,type_desc
,create_date
,modify_date
FROM sys.objects
WHERE create_date > GETDATE() - [No_Of_Days_Old]
ORDER BY create_date;
GO
This above example is a slight variation on the first example shown on the MSDN page that details the sys.objects keyword (A. Returning all the objects that have been modified in the last N days).
That page can be found here:
sys.objects (Transact-SQL)
and is a great resource for many different methods of querying the "metadata" of your database objects.
Of course, the above will simply "SELECT" the table name that will need to be deleted and won't actually delete (or DROP) the table from your database.
To achieve this, you will need a mechanism to issue a DROP TABLE command. Unfortunately, the DROP TABLE command won't accept a parameter valued table name (i.e. You can't do DROP TABLE #tablename), but you can build a string/varchar of a complete T-SQL statement and EXECUTE it).
To achieve this, you can use a CURSOR to loop through the results of the earlier SELECT statement, building a new T-SQL command in a string/varchar that will drop the table name. An example of this is below:
DECLARE #tname VARCHAR(100)
DECLARE #sql VARCHAR(max)
DECLARE db_cursor CURSOR FOR
SELECT name AS tname
FROM sys.objects
WHERE create_date > GETDATE() - 7
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #tname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'DROP TABLE ' + #tname
--EXEC (#sql)
PRINT #sql
FETCH NEXT FROM db_cursor INTO #tname
END
CLOSE db_cursor
DEALLOCATE db_cursor
Note that in the above example, I have commented out the line EXEC (#sql). This is the line that actually executes the T-SQL statement in the #sql variable, and since it's a destructive command, I simply commented it out and used a PRINT #sql command instead (the line below). Run this as is, to see what tables you're likely to delete, and when you're happy, uncomment the EXEC (#sql) command and comment out the PRINT #sql command!
You can use this query to get the list of tables that are more than a week old:
SELECT
[name]
,create_date
FROM
sys.tables
WHERE DATEDIFF(day, create_date, getdate()) > 7
So in your SP, you could then write an SP to loop over the tables returned from that query and delete them. You'll have to take into account that if the tables have foreign keys, the order in which you delete them is important, so this idea will probably need some tweeking if that's your scenario.