Is there any simple command to truncate all tables inside a snowflake schema ?
From what I've seen, the truncate table command only works on a single table
There is not such a command as far as I know, but you may use a simple query to generate the required truncate commands, and then run them:
select 'TRUNCATE TABLE ' || TABLE_CATALOG || '.' || TABLE_SCHEMA || '.' || table_name || ';' cmd
from information_schema.tables
where TABLE_CATALOG = 'GOKHAN_DB' and TABLE_SCHEMA='PUBLIC';
Of course, you can also create a stored procedure (with JS) for this purpose.
Related
I've got two logins, let's call them 1 and 2, and two databases, again 1 and 2, both databases and both logins made using the same sets of instructions. Login1 uses database1 and login2 uses database2.
I'm running this script from an application to do an amendment to a table:
sqlcmd -U {loginID} -P {password} -S SVR09\SQL2019 -h-1 -e -b -i {path}stl_u92_001_o_accref_new_column.sql -o {path}stl_u92_001_o_accref_new_column.log
The loginid, password and paths are all correct because in all cases I get the log file
The SQL script contains this:
-- add new column to the table?
IF NOT EXISTS (SELECT 'X'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'O_ACCREF'
AND COLUMN_NAME = 'ALIAS_ID'
)
ALTER TABLE O_ACCREF
ADD ALIAS_ID varchar(70)
DEFAULT ' ' NOT NULL;
UPDATE O_ACCREF
SET ALIAS_ID = ACC_ALIAS
WHERE ALIAS_ID = ' ';
This is the table before the script is run:
CREATE TABLE dbo.O_ACCREF
(
OUR_BIC VARCHAR(11) DEFAULT ' ' NOT NULL
, THEIR_BIC VARCHAR(11) DEFAULT ' ' NOT NULL
, ACC_ALIAS VARCHAR(70) DEFAULT ' ' NOT NULL
, ORIGIN VARCHAR(1) DEFAULT ' ' NOT NULL
, ACC_CUST VARCHAR(11) DEFAULT ' ' NOT NULL
, ACCOUNT VARCHAR(35) DEFAULT ' ' NOT NULL
)
ON [PRIMARY]
and it has 27 rows in my sample data.
With login1 pointing to database1, the script works and I get the new column on the table and the data from ACC_ALIAS in ALIAS_ID. The log file says 27 rows updated.
With login2 pointing to database2, the script fails to add the new column. However, the ALTER TABLE command doesn't give an error, the only error is
Msg 207, Level 16, State 1, ...
Invalid column name 'ALIAS_ID'
for the UPDATE command. If I run the sqlcmd from the command line on the server hosting the installation of SQL Server, I get the same results.
So I tried using login1 pointing to database2 - fails, and login2 pointing to database1 - works.
When I use Management Studio to get the database and login creation scripts, they look identical, apart from the names of course.
Any pointers as to where I'm going wrong would be much appreciated.
As I mention in the comments, the problem is that the entire batch fails if the column doesn't exist. This is because the batch is parsed before it is executed, and at that point the column ALIAS_ID doesn't exist in the table O_ACCREF, and so the compile fails the batch. Columns are not one of the objects that allow for deferred compilation (such as tables, where you can both CREATE and INSERT into the table in the same batch).
As you as using sqlcmd, you can simply separate the batches with a batch separator (GO by default):
-- add new column to the table?
IF NOT EXISTS (SELECT 'X'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'O_ACCREF'
AND COLUMN_NAME = 'ALIAS_ID'
)
ALTER TABLE O_ACCREF
ADD ALIAS_ID varchar(70)
DEFAULT ' ' NOT NULL;
GO
UPDATE O_ACCREF
SET ALIAS_ID = ACC_ALIAS
WHERE ALIAS_ID = ' ';
We have N tables on Oracle server and we wanted to load all those tables from Oracle to SQL server. We are creating dynamic SSIS packages for same which will take the Oracle ServerName, DB name, schema name, tables list etc. and will load all these tables to SQL server. We have added Link Server on SQL Server (SSMS) for Oracle.
But we are not getting the efficient way to do the same. How we can achieve this in a single SSIS package. How we can handle metadata of Oracle tables and creating the same on SQL server ? This SSIS package should create tables dynamically on SQL server as well , for this we tried Temp table in SSIS package.
Since you have to do it with a large number of tables, I'd write a pl/sql procedure something, built around something like this:
declare
v_sql varchar2(1024);
begin
for x in (select owner, table_name from dba_tables where .....)
v_sql := 'created table '||
table_name ||
'#mssql a select * from '||
x.owner || '.' || x.table_name || ';';
exec immediate v_sql;
end loop;
end;
/
or, if you want to look it over before launching, use sql to write sql. In sqlplus:
set echo off feedback off verify off trimsp on pages 0
spool doit.sql
select 'create table '||
table_name ||
'#mssql as select * from '||
owner || '.' || table_name || ';'
from dba_tables
where .....
;
spool off
then check the spooled sql file for any issues before running.
All code above is off the top of my head. There may be minor syntax issues.
I've created a system stored procedure in the Master database which can be run in all databases. I want to run it in all databases at once, here what I use:
use Master
GO
declare #sql nvarchar(1000)
SET #sql = 'USE [?]; EXEC [dbo].[sp_procedure]'
EXEC sp_MSforeachdb #sql
The problem is - not all databases have have similar table and column structure. So inside procedure, I do this before doing any calculations:
if exists(select 1
from
INFORMATION_SCHEMA.TABLES b,
INFORMATION_SCHEMA.COLUMNS c
where
b.TABLE_TYPE = 'BASE TABLE'
and b.TABLE_NAME = 'tablename'
and c.TABLE_NAME = b.TABLE_NAME
and c.COLUMN_NAME = 'columnname')
So, if while running across all databases, there is no table named 'tablename' with column name 'columnname' it should skip procedure for that database and go on to the next database. I have a database which has 'tablename' table, but doesn't have 'columnname' column in this table, and it returns this error:
Invalid column name 'columnname'.
Why that if exists statement goes inside if statement? Shouldn't it terminate as soon as condition is not met? How can I handle this situation?
That is because SQL Engine tries to compile the code, so it checks the code inside IF block.
You have to use that comparison outside the stored procedure, e.g. in your SET #sql = '......' command, but it will not run that SP if the column does not exist.
So you can try something else - build the query (nvarchar variable) inside the SP and execute it as dynamic SQL.
I have an installation script containing the following:
IF NOT EXISTS(
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_CATALOG = 'mydatabasename'
AND TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'sometablename'
AND TABLE_TYPE = 'BASE TABLE'
)
CREATE TABLE dbo.sometablename ...
Problem is that
I have to allow the user to select a different database name
I cannot use any placeholders ("variables") in the script.
the database server may of course contain a different database which already contains a table sometablename
The installer does a USE mydatabasename before the script is executed; and the installer allows to select a variable database name for this. However, I can't use that variable inside the script, because every replacement in the SQL script is already done at build time of the installer.
So, how can I check whether the used database already contains table sometablename?
Just remove TABLE_CATALOG from your query. All tables in the INFORMATION_SCHEMA.TABLES view belong to the current database.
You may select the name of the actual database in use and replace it in an execute statement.
declare #dbname varchar(50) -- Adjust to your longer database name length.
set #dbname = db_name()
if not exists (
select 1
from information_schema.tables
where table_catalog = #dbname
and table_schema = 'dbo'
and table_name = 'someTableName'
and table_type = 'base table'
) begin
execute (
'create table ' + #dbname + '.dbo.someTableName (
someFieldName someDataType
...
)'
)
end
Otherwise, it always uses the current database so that it considers the database currently in used selected through your use statement.
SQL SERVER – Get Current Database Name
You can still use the SQL Script replacement support from Advanced Installer.
Indeed, the replacement is done at build time, but the properties referenced are resolved at install time, so you can use the database name selected by the user. Just set the field "Replace with" correctly: [SELECTED_DB]
The replacement in the script is done at build time because you cannot write directly the properties as formatted in the script (syntax restrictions).
I'd like to remove all default values that have been setup in a particular database, is there a script that I can run to do this for all tables in database? Could be a bit time consuming without ... any help would be appreciated!
If you're on SQL Server 2005 and up, you could use this script to create another script which will then drop all your default constraints:
SELECT
'ALTER TABLE dbo.' + OBJECT_NAME(parent_object_id) +
' DROP CONSTRAINT ' + Name
FROM
sys.default_constraints
This will create as output a series of statements such as
ALTER TABLE dbo.YourTable DROP CONSTRAINT DF_T_YourColumn
Copy the output into another SQL Server Management Studio query window and execute it and you should be done!
Marc
You could generate a script to drop all default constraints:
SELECT 'alter table ' + object_name(parent_object_id) +
' drop constraint ' + name
FROM sys.objects
WHERE type = 'D'