Using Like on a Parameter Variable? - sql

Select Column1 From Table Where #Variable Like '%' + Column2 + '%'
Doesn't seem to work how I thought it would. Any suggestions?

(vague question)
Have you got Category and #Variable round the wrong way: sqlFiddle
create table the_table
(
category varchar(10),
[Date] datetime,
Amount decimal(12, 2)
)
insert into the_table
values
( 'X', '2012-1-1', 10),
( 'X', '2012-1-3', 10),
( 'Y', '2012-1-3', 20),
( 'Y', '2012-1-5', 10)
declare #Variable varchar(10)
set #Variable = 'Y'
Select *
From the_table
--Where #Variable Like '%' + category + '%'
Where category Like '%' + #Variable + '%'

If you have a limited number of columns, you can use case:
where case
when #Variable = 'col1' then col1
when #Variable = 'col2' then col2
when #Variable = 'col3' then col3
...
end like '%' + Column2 + '%'
Another option is dynamic SQL:
declare #sql nvarchar(max)
set #sql = 'Select Column1 From Table Where ' + #Variable +
' Like ''%'' + Column2 + ''%'''
exec (#sql)

Related

How to use dynamic filter in sql procedure?

I want use Dynamic filter in sql Procedure
,like this
Select * from Table Where #Filter
Can I Write Like That Or Was Diffrent Ways to Use
I must Use this Syntax because I Want Remove Select in Application and Use Procedure.
CREATE PROCEDURE SP_DynamicFilter
(
-- Optional Filters for Dynamic Search
#COLUMN1 INT = NULL,
#COLUMN2 NVARCHAR(50) = NULL,
#COLUMN3 NVARCHAR(50) = NULL,
#COLUMN4 NVARCHAR(50) = NULL
)
AS
BEGIN
SELECT *
FROM TableName
WHERE
(#COLUMN1 IS NULL OR Column1 = #COLUMN1)
AND (#COLUMN2 IS NULL OR Column2 LIKE '%' + #COLUMN2 + '%')
AND (#COLUMN3 IS NULL OR Column3 LIKE '%' + #COLUMN3 + '%')
AND (#COLUMN4 IS NULL OR Column4 LIKE '%' + #COLUMN4 + '%')
END
CREATE PROCEDURE spProcedurName
#Filter datatype
AS
BEGIN
SELECT *
FROM Table
WHERE columnName= #Filter
END
You can paramater like that.
#Query='
Select * from table' + #Filter
exec #Query

Dynamic Create column in sql server with datatype

I have table TAB_A
COL_NAME DATATYPE MAX_LENGTH
A VARCHAR 255
B INT 4
C FLOAT 8
I want to create A,B,C as column in TAB_B with DATATYPE and MAX_LENGTH.
The TAB_B columns look like this: Before
X Y Z
I want the TAB_B look like this: After
X Y Z A B C
with datatype.
How can I write dynamic SQL so my A,B,C,... columns will get created in existing table.
Try below,
I have created sample table like your example:
CREATE TABLE Tab_A
(
COL_NAME CHAR(1),
DATATYPE VARCHAR(100),
MAX_LENGTH INT
)
insert into Tab_A values('A', 'VARCHAR', 255)
insert into Tab_A values('B', 'INT' , 4)
insert into Tab_A values('C', 'FLOAT' , 8)
Now I have created other table Tab_B,
CREATE TABLE Tab_B
(
X CHAR(1),
Y VARCHAR(100),
Z INT
)
SELECT * from Tab_B
Now, Finally I'm using dynamic query,
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName = ISNULL(#ColumnName + ',', '')
+ QUOTENAME(COL_NAME) + ' ' + DATATYPE + CASE WHEN DATATYPE = 'INT' THEN '' ELSE '(' + CAST(MAX_LENGTH AS VARCHAR(10)) +')' END
FROM (
SELECT DISTINCT *
FROM Tab_A
) AS Courses
DECLARE #SQL VARCHAR(1000)
SELECT #SQL = 'ALTER TABLE Tab_B ADD ' + #ColumnName + ''
EXEC (#SQL)
SELECT * FROM Tab_B
This statement will provide the desired query:
DECLARE #TAB_A SYSNAME = 'dbo.Tab_A'
, #TAB_B SYSNAME = 'dbo.Tab_B'
DECLARE #dynsql NVARCHAR(MAX)
SELECT #dynsql = COALESCE(#dynsql,'') + qry
FROM (
SELECT
'ALTER TABLE ' + #TAB_B + ' ADD COLUMN '
+ COLUMN_NAME
+ ' ' + DATA_TYPE
+ CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN ' ' WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN '(MAX) ' ELSE '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) + ') ' END
+ CASE WHEN IS_NULLABLE = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
+ CASE WHEN COLUMN_DEFAULT IS NULL THEN '' ELSE ' DEFAULT ' + COLUMN_DEFAULT END
+ '; ' AS qry
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = PARSENAME(#TAB_A,1)
AND TABLE_SCHEMA = COALESCE(PARSENAME(#TAB_A,2),'dbo')
) r
SELECT #dynsql
Now you can also replace the
SELECT #dynsql
with
EXEC(#dynsql)
but be aware that your table A will be altered when executing.

Selecting columns from a query

I'm using a request to get a collection of columns name:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [...]
From this collection, I'd like to count every not null, not empty value from the original table group by column name.
Let's say I have a table containing
COL1 | COL2 | COL3
------------------
VAL1 | VAL2 | NULL
VAL3 | | VAL4
VAL5 | |
I'm looking for a request to get:
COL1 | 3
COL2 | 1
COL2 | 1
It's for analytics purpose.
Thanks for your help!
Here is a simple process. Run the following query:
SELECT 'SELECT ''' + COLUMN_NAME + ''', COUNT(['+COLUMN_NAME']) as NotNull FROM [' +SCHEMA_NAME+ '].['+TABLE_NAME+ '] union all '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [...]
Copy the results into a query window, remove the final union all, and run the query.
The below code seems to work for your issue
create table sample
(
col1 varchar(10),
col2 varchar(10),
col3 varchar(10)
)
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL1 ',' VAL2 ',NULL);
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL3 ',' ',' VAL4');
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL5 ',' ',' ');
DECLARE #cols1 NVARCHAR(MAX);
DECLARE #sql NVARCHAR(MAX);
SELECT #cols1 = STUFF((
SELECT ', COUNT(CASE WHEN len(['+ t1.NAME + '])!=0 THEN 1 END) AS ' + t1.name
FROM sys.columns AS t1
WHERE t1.object_id = OBJECT_ID('sample')
--ORDER BY ', COUNT([' + t1.name + ']) AS ' + t1.name
FOR XML PATH('')
), 1, 2, '');
SET #sql = '
SELECT ' + #cols1 + '
FROM sample
'
EXEC(#sql)
Hereis my little longer take on this:
declare #cols table (colID integer, colName varchar(50))
declare #results table (colName nvarchar(50), valueCount bigint)
-- table name
declare #tableName nvarchar(50) = 'INSERT TABLE NAME HERE'
-- select column names from table
insert into #cols
select column_id, name from sys.columns where object_id = object_id(#tableName) order by column_id
declare #currentColID int = 0
declare #currentName nvarchar(50) = ''
declare #currentCount bigint = 0
declare #sql nvarchar(max) -- where the dynamic sql will be stored
-- go through all columns
while (1 = 1)
begin
-- step by id
select top 1 #currentColID = c.colID, #currentName = c.colName from #cols c
where c.colid > #currentColID order by c.colID
if ##ROWCOUNT = 0 break;
-- dynamic query to get non-empty, not-null counts
select #sql = 'select #p1=COUNT(' + #currentName + ') from ' + #tableName +
' where ' + #currentName + ' is not null or LEN(' + #currentName + ') > 0'
exec sp_executesql #sql, N'#p1 bigint output', #p1 = #currentCount output
-- insert result to buffer
insert into #results values (#currentName, #currentCount)
end
-- print the buffer
select * from #results
Have fun :)

change conditions when parameter is null

I have a stored procedure like this
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
AND
column2
IN
(
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
AND
column4
IN
(
SELECT * FROM
fn_SplitWords(#param3,',')
)
)
what i want to happen is when #param1 IS NOT NULL #param2 IS NULL AND #param3 IS NULL, the stored procedure will be like:
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
and when #param2 IS NOT NULL AND #param3 IS NULL, the stored procedure will be like this:
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
AND
column2
IN
(
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
)
I already visited
WHERE IS NULL, IS NOT NULL or NO WHERE clause depending on SQL Server parameter value
and Stored procedure to handle null parameter
but I believe that this is a different case.
What might be the possible approach for this?
You can do something like this:
SELECT * FROM Table1
WHERE
column1 LIKE '%' + ISNULL(#param1, column1) + '%' AND
column2 LIKE '%' + ISNULL(#param2, column2) + '%' AND
...
This filters on every field if the parameter is set.
You can dynamically build your sql statement and then executesql proc to execute your query something like this...
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N'SELECT * FROM Table1
WHERE 1 = 1 '
IF (#param1 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column1 LIKE ''%#param1%'''
END
IF (#param2 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column2 IN (
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
)'
END
IF (#param3 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column4
IN
(
SELECT * FROM
fn_SplitWords(#param3,'','')
)
'
END
EXECUTE sp_executesql #Sql
, N'#param1 VARCHAR(100),#param2 VARCHAR(100),#param3 VARCHAR(100)'
, #param1, #param2, #param3

Find columns that contain only zeros

I'm working with SQL Server 2008. I have a list of column names on a table and I'd like to know how to use SQL to return the names of those columns which contain nothing but zero or NULL values.
declare #T table
(
Col1 int,
Col2 int,
Col3 int,
Col4 int
)
insert into #T values
(1, 0 , null, null),
(0, null, 0 , 1)
select U.ColName
from
(
select count(nullif(Col1, 0)) as Col1,
count(nullif(Col2, 0)) as Col2,
count(nullif(Col3, 0)) as Col3,
count(nullif(Col4, 0)) as Col4
from #T
) as T
unpivot
(C for ColName in (Col1, Col2, Col3, Col4)) as U
where U.C = 0
Result:
ColName
----------
Col2
Col3
The idea behind this is to count the non null values and only keep those with a count of 0.
COUNT will only count non null values.
NULLIF(ColX, 0) will make all 0 into null.
The inner query returns one row with four columns. UNPIVOT will turn it around so you have two columns and four rows.
Finally where U.C = 0 makes sure that you only get the columns that has no values other than null or 0.
Here is a brute force way, since you know all the column names.
CREATE TABLE dbo.splunge
(
a INT,
b INT,
c INT,
d INT
);
INSERT dbo.splunge VALUES (0,0,1,-1), (0,NULL,0,0), (0,0,0,NULL);
SELECT
cols = STUFF(
CASE WHEN MIN(COALESCE(a,0)) = MAX(COALESCE(a,0)) THEN ',a' ELSE '' END
+ CASE WHEN MIN(COALESCE(b,0)) = MAX(COALESCE(b,0)) THEN ',b' ELSE '' END
+ CASE WHEN MIN(COALESCE(c,0)) = MAX(COALESCE(c,0)) THEN ',c' ELSE '' END
+ CASE WHEN MIN(COALESCE(d,0)) = MAX(COALESCE(d,0)) THEN ',d' ELSE '' END,
1, 1, '')
FROM dbo.splunge;
-- result:
-- a,b
GO
DROP TABLE dbo.splunge;
You could probably generate much of this script instead of doing it manually, assuming you know the naming scheme or data type of the columns you want (or just by leaving off the where clause entirely and removing the columns you don't want manually).
SELECT CHAR(13) + CHAR(10) + ' + CASE WHEN MIN(COALESCE(' + name + ',0)) = '
+ 'MAX(COALESCE(' + name + ',0)) THEN '',' + name + ''' ELSE '''' END'
FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.splunge')
-- AND system_type_id = 56
-- AND name LIKE '%some pattern%'
;
The output will look like the middle of the first query, so you can copy & paste and then remove the first + and add the surrounding STUFF and query...
Here's a way that works for any table:
declare #tableName nvarchar(max) = N'myTable'
declare #columnName nvarchar(max)
create table #zeros (column_name varchar(max))
declare c cursor local forward_only read_only for
select column_name
from information_schema.COLUMNS WHERE table_name = #tableName
open c
fetch next from c into #columnName
while ##FETCH_STATUS = 0
begin
declare #retval int
declare #sql nvarchar(max) =
N'set #retval = (select count(*) from ' + #tableName + N' where coalesce(' + #columnName + N', 0) <> 0)'
exec sp_executesql #sql, N'#retval int out', #retval=#retval out
select #retval
if #retval = 0
begin
insert into #zeros (column_name) values (#columnName)
end
fetch next from c into #columnName
end
close c
deallocate c
select * from #zeros
drop table #zeros