SQL - replace nulls with 0 in custom table - sql

I've got really weird logic where I getting my custom table with custom nullable fields.
How can I change all NULL values in the table to 0 ?
Sorry but with custom fields I mean that
I don't know the name of columns !

UPDATE custom_table
SET the_column = 0
WHERE the_column IS NULL;

By querying sys.columns and sys.objects you can generate a query that alters every column to a default value (specified by you) for the column types you want to set a default non-null value for.
Something like this will give you something to look at:
SELECT so.name,
sc.name AS varname ,
st.name AS typename ,
sc.max_length ,
sc.[precision] ,
sc.scale ,
sc.collation_name
FROM sys.columns sc
JOIN SYS.types st ON sc.system_type_id = st.system_type_id
AND sc.user_type_id = st.user_type_id
JOIN sys.objects so ON so.object_id = sc.object_id
You can then attach a cursor for this and run a series of alter/update commands based on typename (column type) and varname (column name).

If you mean in ALL columns, then you could do a very expensive query that will touch all records and columns:
UPDATE mytable
SET
col1 = isnull(col1, 0),
col2 = isnull(col2, 0),
col3 = isnull(col3, 0),
col4 = isnull(col4, 0),
col5 = isnull(col5, 0)
-- etc all the numeric columns *
If you included date columns, they go to '1900-01-01'

UPDATE mytable SET mycol=0 WHERE mycol IS NULL

Related

Insert column names into stored procedure SELECT statement from separate table

I am trying to figure out the best method to insert column names held in Table1 into a SELECT statement running against Table2. This query is running in a stored procedure. That doesn't do a very good job of explaining, so lets say I had these values in Table1:
What I am trying to do is use these column names in the SELECT statement against Table2:
Select -- Column Names
from Table2
where UserId = 3;
I'm not sure if an input parameter could be used in that way or how to pass the values into it. For example:
Select #ColumnNames
from Table2
where UserId = 3;
Or maybe a join to table 2?
Thanks!
You will have to use Dynamic SQL
declare #columns varchar(1000)
declare #sql varchar(8000)
select #columns='', #sql=''
select #columns=#columns+value+',' from table1
set #columns=left(#columns,len(#columns)-1)
set #sql='select '+#columns+' from table2'
exec(#sql)
But beware of SQL Injection and read www.sommarskog.se/dynamic_sql.html
You could query the system tables to get the column(s) i.e. (take out WHERE clause to see all the tables and columns)
SELECT tab.name AS TableName,
col.name AS ColName,
tp.name AS SType,
col.max_length,
col.[precision],
(CASE col.is_nullable
WHEN 1 THEN 'true'
WHEN 0 THEN 'false'
ELSE 'unknown'
END) AS Is_Nullable
FROM sys.tables as tab
LEFT OUTER JOIN sys.columns AS col
ON tab.object_id = col.object_id
LEFT OUTER JOIN sys.types AS tp
ON col.system_type_id = tp.system_type_id
WHERE tab.name = 'Table1'
ORDER BY tab.name,col.name

Check to see if table exists and if table is null

I'm building a package in SSIS that first acquires source data from from another server and loads into my server. From there I have another package that manipulates this source data and loads a new table.
I want to prevent this 'manipulation' package from running if something failed on my 'source' package. I can talk it out but not Syntax it out...
If MyTABLE exists and count(*) from MyTABLE > 0 then 'GOOD' else 'BAD' I was going to have a constraint that wouldn't run the rest of the package if anything came back bad. If this is an asinine way of achieving this then please show me the easier way to achieve this.
The ultimate goal would be to have a list of 'GOOD' or 'BAD' and the table name as the next column so if anything fails I can get an email of my query that would quickly show me what is bad and what is good.
Source_Check Source_Table
GOOD TABLE1
BAD TABLE2
GOOD TABLE3
etc.....
my issue is I get an error trying to count(*) from a table that doesn't exist... Not sure how to overcome this :(
There are probably easier ways to go about this, I'm just a newb is all. Could phrase my search right to get any results from google.
Metadata is going to be your friend. Assuming SQL Server, you can write a simple query like
SELECT
*
FROM
sys.schemas AS S
INNER JOIN sys.tables AS T
ON T.schema_id = S.schema_id
WHERE
S.name = N'dbo'
AND T.name = N'SomeTable';
If that returns a result, then you know your table exists.
The problem with SELECT COUNT(*) is that the table must exist. It also locks forces you to crawl the table. There are tricks for addressing this but my favorite is to go back to the metadata well. Look at this query. It's going to generate a list of all the tables and their row counts in no time at all.
SELECT
s.[Name] as [Schema]
, t.[name] as [Table]
, SUM(p.rows) as [RowCount]
FROM
sys.schemas s
LEFT OUTER JOIN
sys.tables t
ON s.schema_id = t.schema_id
LEFT OUTER JOIN
sys.partitions p
ON t.object_id = p.object_id
LEFT OUTER JOIN
sys.allocation_units a
ON p.partition_id = a.container_id
WHERE
p.index_id in(0,1) -- 0 heap table , 1 table with clustered index
AND p.rows is not null
AND a.type = 1 -- row-data only , not LOB
GROUP BY
s.[Name]
, t.[name]
ORDER BY
1
, 2
Now you can compare that resultset to your list of tables that may or may not exist.
You could try something like this:
DECLARE #SourceTables TABLE (tbl_name VARCHAR(100))
INSERT INTO #SourceTables VALUES('TABLE1'),('TABLE2'),('TABLE3');
WITH CTE
AS
(
SELECT o.name AS tbl_name,
i.[Rows] AS row_count
FROM sysindexes i
INNER JOIN sysobjects o
ON i.id = o.id
WHERE i.IndId < 2
AND xtype = 'U'
)
--Returns tables that don't exist
SELECT CASE
WHEN B.tbl_name IS NULL AND B.row_count > 0 --when there is no table and row count is greater than 0, then good
THEN 'Good'
ELSE 'Bad'
END AS Source_Check,
A.tbl_name
FROM #SourceTables A
LEFT JOIN CTE B
ON A.tbl_name = B.tbl_name
Theoretical Results:
Source_Check tbl_name
------------ -------------------------
Good TABLE1
Good TABLE2
Bad TABLE3
I assume you're using SQL Server based on the SSIS package. You could simplify things using OBJECT_ID Try Something Like the following....
CREATE TABLE #OUTPUT(Source_Check VARCHAR(10), Source_Table VARCHAR(10))
IF OBJECT_ID('DBNAME.dbo.Table1') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE1')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE1')
END
IF OBJECT_ID('DBNAME.dbo.Table2') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE2')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE2')
END
IF OBJECT_ID('DBNAME.dbo.Table3') IS NOT NULL
BEGIN
INSERT INTO #OUTPUT VALUES ('GOOD', 'TABLE3')
END
ELSE
INSERT INTO #OUTPUT VALUES ('BAD', 'TABLE3')
END
SELECT * FROM #OUTPUT

Finding out if a column is NOT NULL

I have a column in my DB which is currently defined as NOT NULL.
I would like to update this column to allow NULLs.
I have the following script to do this however I would like to check first if the column is already NULL (or NOT NULL), as it may have been changed previously.
ALTER TABLE [dbo].[aud]
ALTER COLUMN [actname] nvarchar(50) NULL
Any help appreciated.
Use COLUMNPROPERTY to get column property . You may write something like
SELECT COLUMNPROPERTY(OBJECT_ID('dbo.aud'),'actname','AllowsNull') AS 'AllowsNull';
For more information please visit this link
select is_nullable from sys.columns c inner join sys.tables t on
t.object_id = c.object_id where t.name = 'aud' and c.name = 'actname'
Will give you a BIT representing whether it is nullable or not.
So you could switch on this like
IF EXISTS(SELECT * from sys.columns c inner join sys.tables t on
t.object_id = c.object_id where t.name = 'aud' and c.name = 'actname' AND
is_nullable = 1)
BEGIN
--What to do if nullable
END
ELSE
BEGIN
--What to do if not nullable
END
END
That of course assumes that the table and column exist at all...
There isn't really a need to do that, because if it's already Nullable, changing a column from Nullable to Nullable will have no negative effect.
However you can do it with this query:
SELECT is_nullable
FROM sys.columns
WHERE object_id=object_id('YourTable') AND name = 'yourColumn'

Doubt in Query - SQL Server 2005

I am having table with 100 columns. here up to 50 to 60 columns contains NULL value in it. Now i need to Replace this NULL value to 0 in all 50 to 60 columns. I tried with the Update query as,
UPDATE [tableName]
SET col1=0, col2 = 0, ... col60 = 0
WHERE col1 IS NULL AND Col2 IS NULL ... Col60 IS NULL
Is there anyother Query to update these all 60 columns without specifying such columns or we have any other approach???
You have to specify all columns, but you can skip the WHERE clause and have one update deal with them all at once:
UPDATE [tableName] SET
col1=COALESCE(col1, 0),
col2=COALESCE(col2, 0),
col3=COALESCE(col3, 0),
col4=COALESCE(col4, 0),
[...]
You could try this workaround if every value in the columns is NULL:
Edit the table definition and set the columns as "Calculated" and use 0 as formula
Save the table
Remove the formula
It is not very elegant but works
I don't think there's an alternative - but the query you posted will only update records where all the columns are null.
If you want to update individual columns, you need to break it up into individual updates:
update table
set col1 = 0
where col 1 is null
update table
set col2 = 0
where col2 is null
To do not write this query by hand, you can generate this by using dynamic SQL:
DECLARE #Table NVARCHAR(255)= 'Your table'
DECLARE #sSQl NVARCHAR(MAX)= 'UPDATE ' + #Table + ' SET ' + CHAR(13) ;
WITH c AS ( SELECT c.name
FROM sys.all_columns c
JOIN sys.tables T ON c.object_id = T.object_id
WHERE t.name = #Table
)
SELECT #sSQl = #sSQl + c.name + '=ISNULL(' + c.name + ',0)' + ','
+ CHAR(13)
FROM c
IF LEN(#sSQl) > 0
SET #ssql = LEFT(#sSQl, LEN(#sSQl) - 2)
PRINT #ssql

How to identify whether the table has identity column

I want to find out whether the table has an identity column or not. Table is unknown to me. I have not done the structure of the table. Using Query?
I am using Sql Server Compact Edition.
IF (OBJECTPROPERTY(OBJECT_ID('TABLE_NAME'), 'TableHasIdentity') = 1)
ObjectProperty is available starting sql server 2008 Reference:
OBJECTPROPERTY
This query returns a table's identity column name:
CREATE PROCEDURE dbo.usp_GetIdentity
#schemaname nvarchar(128) = 'dbo'
,#tablename nvarchar(128)
AS
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) AS TABLENAME,
NAME AS COLUMNNAME,
SEED_VALUE,
INCREMENT_VALUE,
LAST_VALUE,
IS_NOT_FOR_REPLICATION
FROM SYS.IDENTITY_COLUMNS
WHERE OBJECT_NAME(OBJECT_ID) = #tablename
AND OBJECT_SCHEMA_NAME(object_id) = #schemaname
END
Then form the code side.
Call this stored procedure using the datareader role, then check datareader.hasrows(). If the condition value is true (1), then the table has identity column if set. If not then it doesn't have an identity column.
I know it's long time ago but i found this helpful
try this :
IF EXISTS (SELECT * from syscolumns where id = Object_ID(#TABLE_NAME) and colstat & 1 = 1)
BEGIN
-- Do your things
END
Any of the below queries can be used to check if an Identity Column is present in the table
1)
SELECT *
FROM sys.identity_columns
WHERE OBJECT_NAME(object_id) = 'TableName'
2)
SELECT *
FROM sys.identity_columns
WHERE object_id = (
SELECT id
FROM sysobjects
WHERE name = 'TableName'
)
I would just like to add this option as well as I think it is the simplest
SELECT COLUMNPROPERTY(OBJECT_ID('TableName'),'ColumnName','isidentity')
One way to do this would be to make use of the stored procedure sp_help. I.e:
sp_help MyTable
This will return a DataSet that has all the information you would need on the table. There is a specific Table that has information on identities.
I.e:
If it does not contain an identity field, the Identity column will say: "No identity column defined".
#Pranay: he said Compact Edition. Stored procedures aren't supported, and there is no sys.anything.
This is the call:
SELECT Count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE AUTOINC_INCREMENT IS NOT NULL AND TABLE_NAME='this_table'
It will return either 1 (true) or 0 (false).
...
declare #tblhasIdentCol bit = IF (IDENT_CURRENT( #dbName +'.'+ #schemaName +'.'+ #tableName ) IS NOT NULL , 1 , 0 )
You get numeric value if table has identity
Very simple answer would be to run this:
SELECT IDENT_CURRENT('TABLE-NAME')
This would give max value of identity column if exists, if the column doesn't exist, it gives 1 as result.
Based on max value, you can identify which column is having that and determine the identity column.
This the query that get u all the tableNames, columnnames of the table, and is_identity or not in the selected database
SELECT
sys.columns.name
, sys.tables.name
, is_identity
FROM sys.columns
INNER JOIN sys.tables ON sys.tables.object_id = sys.columns.object_id
AND sys.columns.is_identity = 1
CREATE FUNCTION dbo.fnTableHasIdentity(#Tbl sysname)
RETURNS TINYINT
BEGIN
RETURN OBJECTPROPERTY(OBJECT_ID(#Tbl), 'TableHasIdentity')
END
--As simple as that!
select t.name as TableName,c.name as ColumnName
from sys.identity_columns c
inner join sys.tables t on c.object_id = t.object_id
where t.name = 'TableName'
If you like me, needed to be able to do this for tables in an arbitrary database, then I found the following solution:
IF EXISTS (
SELECT 1
FROM [database name].sys.identity_columns AS id_col
INNER JOIN [database name].sys.objects
ON objects.object_id = id_col.object_id
INNER JOIN [database name].sys.schemas
ON schemas.schema_id = objects.schema_id
AND schemas.name = 'schema name'
WHERE OBJECT_NAME(id_col.object_id, DB_ID('database name')) = 'table name'
) SELECT 1 ELSE SELECT 0
you can get the 1 or 0 Boolean Form if the current table has identity Columns by using this
SELECT Count(Column_ID) FROM sys.identity_columns WHERE OBJECT_NAME(object_id) = 'tableName'
One way to list all Tables with their identity column if it exists
to get you desired table add at the end of the filter "and o.name='TableName'"
where Tbale Nam is the table you are looking for
SELECT o.[Name][TableName],i.[name][IdentityColName] FROM
sys.objects o
left outer join sys.identity_columns i on i.object_id=o.object_id
where o.type='U'