SQL SERVER example with checkbox - sql

Need your help with checkboxes.
Here is my code:
CREATE PROCEDURE stad_list
#inp_location_code numeric (3,0) = -1
#inp_item_code_bgn numeric (5,0) = -1
#inp_item_code_end numeric (5,0) = -1
#inp_shipped numeric (2,0) = 0, --checkbox, if it is checked then returns the items in table which were shipped (value in table is 1)
#inp_check numeric (2,0) = 0, --checkbox, if it is checked then returns data which is still in process of checking for availability in warehouse (value in table is 0)
#inp_not_ship numeric(2,0) = 0 --checkbox, if it is checked then returns data which had not been shipped during some problems (valuein table is 2)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SELECT as varchar (3000) = ''
DECLARE #WHERE as varchar (1000) = ''
IF (#inp_location_code != -1)
SET #WHERE = #WHERE + ' WHERE [dbo].item.location =' + CONVERT(varchar,#inp_location_code)
IF (#inp_item_code_bgn != -1)
SET #WHERE = #WHERE + ' AND [dbo].item.code>=' + CONVERT(varchar, #inp_item_code_bgn)
IF (#inp_item_code_end != -1)
SET #WHERE = #WHERE + ' AND [dbo].item.code<=' + CONVERT(varchar, #inp_item_code_end)
IF (#inp_shipped = 1)
SET #WHERE = #WHERE + ' AND [dbo].item.ship = 1'
IF (#inp_check = 1)
SET #WHERE = #WHERE + ' AND [dbo].item.ship = 0'
IF (#inp_not_ship = 1)
SET #WHERE = #WHERE + ' AND [dbo].item.ship = 2'
SET #SELECT = #SELECT + '
SELECT
[dbo].item.name as ''NAME'',
[dbo].item.location as ''LOCATION'',
[dbo].item.code as ''CODE'',
[dbo].item.ship as ''STATUS''
FROM [dbo].item '
+ #WHERE
EXEC (#SELECT)
RETURN ##ROWCOUNT
END
It works fine when i am checking only one check box, but cant get any data while 2 of it are checked. So what to do in case when i want to check two check boxes? Any suggestions?
here is my table
Id Item_code Item_name Item_location Item_ship
1 14789 Juice Tokyo 0
2 14785 Boots Tokyo 2
3 98744 Hat Osaka 0
4 36987 Socks Kyoto 1
And there is three checkboxes
Shipped
Checking
Not shipped
If i check shipped then output will be like this:
Id Item_code Item_name Item_location Item_ship
4 36987 Socks Kyoto 1
but i want to do so for ex. when i check Shipped and Checking then the output will be:
Id Item_code Item_name Item_location Item_ship
1 14789 Juice Tokyo 0
3 98744 Hat Osaka 0
4 36987 Socks Kyoto 1

Use temp table as table of parameters
IF (#inp_shipped = 1) OR (#inp_check = 1) OR (#inp_not_ship = 1)
BEGIN
IF OBJECT_ID('tempdb.dbo.#Parameters') IS NOT NULL DROP TABLE dbo.#Parameters
SELECT *
INTO #Parameters
FROM (
SELECT CASE WHEN #inp_shipped = 1 THEN 1 END AS Ship
UNION ALL
SELECT CASE WHEN #inp_check = 1 THEN 0 END
UNION ALL
SELECT CASE WHEN #inp_not_ship = 1 THEN 2 END
) p
WHERE p.Ship IS NOT NULL
SET #WHERE = #WHERE + ' AND [dbo].item.ship IN (SELECT ship FROM #Parameters)'
END
For better performance(made ​​to use index seek operation) if you have an index on the ship column, need to create an index on a temporary table:
CREATE INDEX x ON #Parameters(ship)

You could combine you options into this kind of construction:
declare #orcheck varchar(255)
set #orcheck = 'AND 1=2 ('
IF (#inp_shipped = 1)
SET #orcheck = #orcheck + ' OR [dbo].item.ship = 1'
IF (#inp_check = 1)
SET #orcheck = #orcheck + ' OR [dbo].item.ship = 0'
IF (#inp_not_ship = 1)
SET #orcheck = #orcheck + ' OR [dbo].item.ship = 2'
set #orcheck = #orcheck + ')'
This way, when you have all 3 checkboxes selected, the WHERE clause would look like this:
AND (1=2
OR [dbo].item.ship = 1
OR [dbo].item.ship = 0
OR [dbo].item.ship = 2
)
And when nothing is select, it would be:
AND (1=2
)
Which is what you expect, I believe.

Related

Why won't my query in a dynamic SQL work as intended?

I believe I have a formatting problem in the query but I need a second set of eyes to help me please.
select #InsertSQL = ' Insert Into #ResultSet('
+ 'UserDomainMappingId,'
+ 'UserId,'
+ 'UserName,'
+ 'Domain,'
+ 'DomainName,'
+ 'LastUpdatedBy,'
+ 'LastUpdatedByName,'
+ 'LastUpdatedAt)'
select #SelectSQL = ' select '
+ 'UD.UserDomainMappingId,'
+ 'UD.UserId,'
+ '(select FullName from Users where UserId = UD.UserId),'
+ 'UD.Domain,'
+ '(select Name from ReferenceCodes RC where RC.Type = ''DOMAIN'' and RC.Code = ''' + #Domain + '''),'
+ 'UD.LastUpdatedBy,'
+ '(select FullName from Users where UserId = UD.LastUpdatedBy),'
+ 'UD.LastUpdatedAt'
select #FromSQL = ' from UserDomainMapping UD '
select #WhereSQL = 'where UserDomainMappingId = UD.UserDomainMappingId '
I'm expecting:
the select for DomainName to work, as it does if I remove the quotes and hardcode the scaler, but it doesn't inside the dynamic sql. Any ideas? Thanks.
Concatenating string in SQL has a tendency to NULL the result if any of the values is NULL. Made a little example you can try:
declare #A varchar(100), #B varchar(100), #C varchar(100)
set #A = 'a'
set #B = 'b'
set #C = #A + #B
select #C --'ab'
set #A = null
set #B = 'b'
set #C = #A + #B
select #C --NULL
set #A = 'a'
set #B = null
set #C = #A + #B
select #C --NULL
set #A = 'a'
set #B = null
set #C = #A + isnull(#B ,'')
select #C --'a'
So, basically you get an empty query, because #Domain is NULL. For that I suggest to use isnull(#Domain,'')

How to update table with while loop in Stored Procedure?

I want to update my dynamic table in while loop.
Here is my code:
While (#j<=#tmp_getRowCount)
Begin
Set #firstcolumn = (Select SplitFirst_tblAR from #result_AR Where rownumber = #j) //String//
Set #secondcolumn = (Select EMail_tblAR from #result_AR Where rownumber = #j) //String//
Set #thirdcolumn = (Select SplitFirst_tblKul from #result_AR Where rownumber = #j) //String//
Set #fourthcolumn = (Select EMail_tblKul from #result_AR Where rownumber = #j) //String//
insert into #test Values(#tmp_ID, #firstcolumn,#secondcolumn,#thirdcolumn,#fourthcolumn)
if ((#firstcolumn = #thirdcolumn) AND (#secondcolumn != #fourthcolumn) AND (#firstcolumn != ''))
begin
Set #q_updateTable = 'Update '+ quotename(#tablename) +' Set '+#columnname+' = ''' + #fourthcolumn + ''' Where ID = ' + #tmp_ID + ''
Exec sp_executesql #q_updateTable
end
SET #j = #j+1
End
My result_AR table:
I know the error is in here:
Where ID = ' + #tmp_ID + ''
When I change this Where clause as,
Where '+#columnname+' = ''' + #secondcolumn + ''' '
code works correctly.
Why can't I set as ID my where clause? I am getting ID value as integer.
The error is 'Query completed with errors'.
Thanks in advance.
you can not set Id in where clause because the id is integer value and you are concatenating it with string (varchar).
So first you have to convert it in (String)varchar and the you can use it where clause.
Like :
Set #q_updateTable = 'Update '+ quotename(#tablename) +' Set '+#columnname+' = ''' + #fourthcolumn + ''' Where ID = ' + convert(varchar,#tmp_ID) + ''
Exec sp_executesql #q_updateTable
you have to use "convert(varchar,#tmp_ID)" insted of "#tmp_ID"

Dynamic SQL for CASE Statements to remove hardcode

I've a Dynamic SQL that is required to be optimized. I need to make CASE Expression Dynamic. I've a list of ATTRIBUTE_LIST & SCENARIO_LIST, that are provided below. I wrote a Function to get them Dynamically. How can I replace Three CASE Expression and make it Dynamic? I'm trying to avoid hard coding.
SET #ATTRIBUTE_LIST = 'symbol_type, currency, performing_status' -- INPUTS
SET #SCENARIO_LIST = 'historicalsimulation_1day_end_10dec2013, historicalsimulation_1day_end_11dec2013'
SELECT CASE
WHEN (GROUPING(Scenario_Name) = 1) THEN ''ALL''
WHEN (Scenario_Name = ''[BaseCase]'') THEN ''BaseCase''
ELSE ISNULL(Scenario_Name, '''')
END AS Scenario_Name,
CASE
WHEN (GROUPING(Symbol_Type) = 1) THEN ''ALL''
ELSE ISNULL(Symbol_Type, '''')
END AS Symbol_Type,
CASE
WHEN (GROUPING(Currency) = 1) THEN ''ALL''
ELSE ISNULL(Currency, '''')
END AS Currency,
CASE
WHEN (GROUPING(Performing_Status) = 1) THEN ''ALL''
ELSE ISNULL(Performing_Status, '''') \
END AS Performing_Status,
SUM(Value) AS ScenarioValue
FROM [20151005_171003_UserName_NT-22_Analysis_Tue] o
LEFT JOIN [20151005_171003_UserName_NT-22_Analysis_Tue_Position_Data] pld
ON o.Position_Unique_Identifier=pld.Position_Unique_Identifier
GROUP BY ' + #ATTRIBUTE_LIST + ' WITH CUBE) AS DATA
PIVOT ( Sum(scenariovalue)
FOR scenario_name IN (' + #SCENARIO_LIST + ')'
It appears you are using SQL Server. Here's a brute-force way of looping over your attributes and building a series of case expressions:
declare #cases nvarchar(max) = '';
declare #l varchar(max) = #ATTRIBUTE_LIST + ',';
declare #ofs int = 0;
declare #pos int = charindex(',', #l, #ofs + 1);
while #pos > 0
begin
if #cases <> '' set #cases = #cases + ',';
set #cases = #cases +
replace('
CASE WHEN (GROUPING(<COL>) = 1) THEN ''ALL''
ELSE ISNULL(<COL>, '''')
END AS <COL>',
'<COL>', substring(#l, #ofs + 1, #pos - #ofs - 1)
);
set #ofs = #pos;
set #pos = charindex(',', #l, #ofs + 1);
end
select #cases;

Multiple conditional Where clause

I currently have a query that will pull a bunch of information from my database based on whatever where condition that I want to use.
declare #CaseNum char(7),
#ImportId char,
#FormatId char,
#SessionId char(5)
set #CaseNum = '' --I can place the value that I want to search by in here
set #ImportId = ''
set #FormatId = ''
set #SessionId = ''
--------------------
query in here
--------------------
where
gr.[CaseNum] = #CaseNum --currently I have to comment the ones I'm not using out
--im.[ImportId] = #ImportId
--fr.[FormatId] = #FormatId
--se.[SessionId] = #SessionId
I want to be able to take the comment portion out and simply display all rows if the parameter = ''
For example if I use set #CaseNum = '1234567' then it will search by that parameter and if I use #FormatId = '12' it will search by that one.
I have tried using the following and a few other attempts but I am getting nowhere fast.
where
gr.[CaseNum] = '%' + #CaseNum + '%'
and im.[ImportId] = '%' + #ImportId + '%'
and fr.[FormatId] = '%' + #FormatId + '%'
and se.[SessionId] = '%' + #SessionId + '%'
With help from the link that #Norman posted I figured it out. I wanted to post my solution for others to see.
declare #CaseNum varchar(MAX),
#ImportId varchar(MAX)
set #CaseNum = ''
set #ImportId = ''
----------------------------------------------------------------------------
If(#CaseNum = '') --Sets the parameter to NULL for COALESCE to work
Begin
Select #CaseNum = NULL
End
If(#ImportId = '') --Sets the parameter to NULL for COALESCE to work
Begin
Select #ImportId = NULL
End
--------------------
query in here
--------------------
where
gr.[CaseNum] = COALESCE(#CaseNum, gr.[CaseNum])
and im.ImportId = COALESCE(#ImportId, im.ImportId)
This solution allows the query to use just a single parameter or all at the same time.
You might want to look into building your query.
DECLARE #Number varchar(10)
DECLARE #Where varchar(max)
DECLARE #Query varchar(max)
SET #Query = 'SELECT * FROM TestTable'
SET #Where = ''
SET #Number = '3'
IF ISNULL(#Number, '') != ''
BEGIN
SET #Where = #Where + 'and testNumber = ' + #Number
END
IF LEN(#Where) > 0
BEGIN
SET #Where = SUBSTRING(#Where, 4, LEN(#Where))
END
if ISNULL(#Where, '') != ''
BEGIN
SET #Query = #Query + ' WHERE ' + #Where
END
EXEC(#Query)
Check out this gentleman's article for reference: https://social.msdn.microsoft.com/forums/sqlserver/en-US/1ec6ddd9-754b-4d78-8d3a-2b4da90e85dc/dynamically-building-where-clauses

PostgreSQL Create new table out of rows

I am using PostgreSQL 9.1
I have the following table containing some settings
setting | content
---------------+---------
enabled | True
reenable_time | 1
count_row | 6
count_col | 3
(4 rows)
And I want to have something like this
enabled | reenable_time | count_row | count_col
---------+-----------------+-------------+----------
True | 1 | 6 | 3
(1 row)
Thank you for your answers!
What you need is cross-tabulation (pivoting), aka turning rows into columns.
If you don't want to hardcode "enabled", "reenable_time", etc., you need to use dynamic SQL.
The basic idea goes like this:
SELECT -- Grab the user_account columns.
acc.id,
acc.email,
-- Use max() combined with a case statement to
-- usher individual attribute values into columns.
max(CASE WHEN (attr.attribute_type = 'first-name')
THEN attr.value END) AS fname,
max(CASE WHEN (attr.attribute_type = 'last-name')
THEN attr.value END) AS lname,
max(CASE WHEN (attr.attribute_type = 'title')
THEN attr.value END) AS title
FROM user_account AS acc
-- Join the attribute table /once/.
LEFT JOIN user_attribute AS attr
ON (attr.user_account_id = acc.id)
WHERE (acc.email = 'foo#example.com')
-- Group by the non-pivoted columns
GROUP BY acc.id,acc.email;
Here a link for further information:
https://sykosomatic.org/2011/09/pivot-tables-in-postgresql/
Here an example from my workplace (it's MS-SQL, but you'll get the idea, PostGre doesn't support the pivot command, it's MS proprietary, so you need to use "case when" with "group by"):
-- ===================================================
-- Author: Stefan Steiger
-- Create date: 14.04.2011
-- Last modified: 17.01.2012
-- Description: Übersetzung für Berichte
-- ===================================================
CREATE PROCEDURE [dbo].[sp_RPT_Report_Translation]
#in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
AS
BEGIN
DECLARE
#strSQL NVARCHAR(MAX)
,#strReportName NVARCHAR(1000)
,#strPivotColumns NVARCHAR(MAX)
,#stichtag DATETIME
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
SET #stichtag = CONVERT(DATETIME, #in_stichtag)
SET #stichtag = CAST(FLOOR(CAST(#stichtag AS Float)) AS DateTime)
SET #in_stichtag = CONVERT(varchar(50), #stichtag)
SET NOCOUNT ON;
SET #strReportName = REPLACE(#in_report_name, N'''', '''''')
-- http://geekswithblogs.net/baskibv/archive/2008/07/03/123567.aspx
SELECT
#strPivotColumns = COALESCE(#strPivotColumns, '') + '[' + [RTR_ItemCaption] + '], '
FROM T_RPT_Translations
WHERE (RTR_Status = 1)
AND (RTR_MDT_ID = #in_mandant)
AND
(
(RTR_ReportName = #strReportName)
OR
(RTR_ReportName = 'PARA_ALL')
)
--AND (RTR_ItemCaption != 'RPT_Title')
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '')
ORDER BY RTR_Sort
SET #strPivotColumns = SUBSTRING(#strPivotColumns, 0, LEN(#strPivotColumns))
SET #strPivotColumns = REPLACE(#strPivotColumns, N'''', '''''')
--PRINT #strPivotColumns
SET #strSQL = '
SELECT TOP(1) * FROM
(
SELECT
RTR_ItemCaption
--,RTR_Kurz_' + #in_sprache + '
,RTR_Lang_' + #in_sprache + '
FROM T_RPT_Translations
WHERE (RTR_MDT_ID = ''' + #in_mandant+ ''')
AND
(
(RTR_ReportName = ''' + #strReportName + ''')
OR
(RTR_ReportName = ''PARA_ALL'')
)
--AND (RTR_ItemCaption != ''RPT_Title'')
AND (RTR_Status = 1)
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '''')
) AS SourceTable
PIVOT
(
MAX(RTR_Lang_' + #in_sprache + ')
FOR RTR_ItemCaption IN
( '
+ #strPivotColumns +
' )
) AS PivotTable
--ORDER BY RPT_RM_SO_Bezeichnung, RPT_RM_GB_Bezeichnung, RPT_RM_NutzungGruppeCode
'
DECLARE #ProzedurParameter nvarchar(max)
SET #ProzedurParameter = '
DECLARE #in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
;
SET #in_mandant = ''' + REPLACE(#in_mandant, '''', '''''') + ''';
SET #in_sprache = ''' + REPLACE(#in_sprache, '''', '''''') + ''';
SET #in_stichtag = ''' + REPLACE(#in_stichtag, '''', '''''') + ''';
SET #in_report_name = ''' + REPLACE(#in_report_name, '''', '''''') + ''';
'
EXECUTE sp_RPT_DEBUG_LOG_ProzedurRun
'sp_RPT_Report_Translation'
,#ProzedurParameter
,#strSQL
,'' --#ProzedurDetail
;
--PRINT #strSQL
EXECUTE (#strSQL)
END
GO