Updating a stored procedure and want to be able to change the name of the column returned dependant on parameter input
I understand the below is not valid but thought it the best way to explain what I want to achieve.... I want to be able to change the name of the column in the select statement dependent on a input parameter...
(
CASE
WHEN (#DateExpired = 1) THEN sens.date1 AS [Expired]
ELSE sens.date1 AS [Due Date]
END
)
I can see how I could do this at whole table select level but did not want to duplicate code for the usual reasons associated with why duplicated code is bad. Any ideas appreciated!
Simply use an IF statement in your stored procedure...
IF #DateExpired = 1
SELECT sens.date1 AS Expired FROM sens
ELSE
SELECT sens.date1 AS [Due Date] FROM sens
If you are worried about the duplicate SQL (perhaps because your query is complex) then you could have your SQL statement insert your required data into a temporary table and then use the IF above replacing "sens" with your temp table and just return the column names from the temp table.
Hope that helps,
Ash
One way is to add both the columns in Select List and add a dummy date which is not feasible from application when condition are not met for that column like:
(
CASE WHEN (#DateExpired = 1) THEN sens.date1 ELSE '01-01-1900' END AS [Expired]
CASE WHEN (#DateExpired <> 1) THEN sens.date1 ELSE '01-01-1900' END AS [Due Date]
)
and then let the client application handle the invalid dates as required by the business..
Related
I am new to SQL Server. My programming background is in SAS. I am currently using SQL Server Management Studio v18.5. I am trying to determine how to solve a couple of problems:
I want to assign new variables to existing columns, depending on the value of those columns. I have read about declaring variables using set and select, but I am having trouble translating that information to what I need to do. I have a view which contains several thousand records. I want the variable logic applied to each record in the view. The desired result is that I create a new view with just the new variable name and other associated data, excluding the original column names.
In SAS, my code would look like:
If newctry<>' ' then countryname = newctry;
else countryname = mailingcountry;
The existing columns are newctry and mailingcountry. The column newctry only has values when the mailingcountry value was invalid, otherwise the record value is blank.
I have different instances of this type of situation. Do I need to create subqueries for each of these instances? If someone could provide an example of how this might work in SQL, I would really appreciate it. An example of the SQL code I have tried is:
DECLARE #countryname VARCHAR(50)
SELECT recordid, recorddate, newctry, mailingcountry
FROM viewname
SELECT #countryname = newctry FROM viewname WHERE newctry <> ' ']
SELECT #countryname = mailingcountry FROM viewname WHERE newctry = ' '
The other question I have is that I have received errors when I have included multiple CASE statements with different END names in the Select statement. Do I need subqueries for each CASE statement?
Thanks!
I think you just want a case expression:
select (case when newctry <> ' ' then newctry else mailingcountry end) as countryname
I have created a temporary table in a stored procedure.
All the values have also been derived in #temptable.
The problem is whenever I try to use a IF statement, it says "Invalid Column" although the column is available on the #temptable. Can somebody summarize me the logic behind it and what should be done for it to not happen again in the future.
For example I have the column "availableBalance" on the #temptable.
Now if I create a IF statement,
(This is just an example)
If (availableBalance>300)
Update status = 01
Else
Status = 02.
It will say "Invalid Column" AvailableBalance.
Please give me a briefing as to "Invalid Column" so that I can do it the right way ?
Use CASE/WHEN instead of IF/ELSE
UPDATE #temptable
SET status =
CASE
WHEN availableBalance > 300 THEN 0
ELSE 02
END
You can use IIF() as
UPDATE #YourTable
SET Status = IIF(AvailableBalance > 300, 0, 1)
--WHERE condition if needed
I am trying to change a column name based on the results of a case statement, is this possible and how would I do it...here is what I have so far but I am not good enough at SQL yet.
I want the change the column name of VALUE to become NUMVALUE if the data is numeric and ALNVALUE if the data isn't numeric. Essentially making a three column datatable a four column datatable. Is this possible?
CASE WHEN ISNUMERIC([Value])=1 THEN SELECT [VALUE] AS [NUMVALUE] ELSE SELECT [VALUE] AS [ALNVALUE] END
No, it isn't possible.
Think about the issues you'd run into when you try and use the result set. Anytime you tried to access the data, you would get an exception stating that the column couldn't be found or similar.
Dim data = Results["ColumnName"] would become unreliable.
You will need to make a separate column for each of them or put them all under the same name.
You need two CASEs = two columns:
SELECT
CASE WHEN ISNUMERIC([Value])= 1 THEN [VALUE] END AS [NUMVALUE],
CASE WHEN ISNUMERIC([Value])<>1 THEN [VALUE] END AS [ALNVALUE],
...
FROM myTable
I understand that AS is used to create an alias. Therefore, it makes sense to have one long name aliased as a shorter one. However, I am seeing a SQL query NULL as ColumnName
What does this imply?
SELECT *, NULL as aColumn
Aliasing can be used in a number of ways, not just to shorten a long column name.
In this case, your example means you're returning a column that always contains NULL, and it's alias/column name is aColumn.
Aliasing can also be used when you're using computed values, such as Column1 + Column2 AS Column3.
When unioning or joining datasets using a 'Null AS [ColumnA] is a quick way to make sure create a complete dataset that can then be updated later and a new column does not need to be created in any of the source tables.
In the statement result we have a column that has all NULL values. We can refer to that column using alias.
In your case the query selects all records from table, and each result record has additional column containing only NULL values. If we want to refer to this result set and to additional column in other place in the future, we should use alias.
It means that "aColumn" has only Null values. This column could be updated with actual values later but it's an empty one when selected.
---I'm not sure if you know about SSIS, but this mechanism is useful with SSIS to add variable value to the "empty" column.
When using SELECT you can pass a value to the column directly.
So something like :
SELECT ID, Name, 'None' AS Hobbies, 0 AS NumberOfPets, NULL AS Picture, '' AS Adress
Is valid.
It can be used to format nicely a query output when using UNION/UNION ALL.
Query result can have a new column that has all NULL values. In SQL Server we can do it like this
SELECT *, CAST(NULL AS <data-type>) AS as aColumn
e.g.
SELECT *, CAST(NULL AS BIGINT) AS as aColumn
How about without using the the as
SELECT ID
, Name
, 'None' AS Hobbies
, 0 AS NumberOfPets
, NULL Picture
Usually adding NULL as [Column] name at the end of a select all is used when inserting into another table a calculated column based on the table you have just selected.
UPDATE #TempTable SET aColumn = Column1 + Column2 WHERE ...
Then exporting or saving the results to another table.
I'm working with a 3rd pary app where I can't alter the tables. We built custom matching "Monthly" tables with an additional datetime column "AsOfDate" where we dump the data at the end of the month and flag those data with the date of last day of the month.
I want to be able to create a single Stored Procedure (Application is designed to require a view or stored proc as the source of all reports.) and use a parameter which will either use the current data table (Parameter may be NULL or = Today's Date) or use the month end table and filter by the End of the month date. This way, I have one report where the user can either use current or data from a particular month end period.
Which would you prefer (And why) Sorry, this is not fully coded
Solution #1 Union Query
Create Proc Balance_Report (#AsOfDate)
AS
Select Column1
From
(Select GetDate() as AsOfDate
, Column1
From Current.Balance
Union
Select AsOfDate
, Column1 From MonthEnd.Balance
) AS All_Balances
Where All_Balances.AsOfDate = #AsOfDate
Solution #2 Use If Statement to select table
Create Proc Balance_Report (#AsOfDate)
AS
If #AsOfDate IS NULL or #AsOfDate = GetDate()
Select GetDate() as AsOfDate
, Column1
From Current.Balance
Else
Select AsOfDate
, Column1 From MonthEnd.Balance
Where AsOfDate = #AsOfDate
Again, this is not fully coded and is sort of db agnostic (But it is SQL Server 2005).
Edit: Variation to Solution #2 using separate stored procedures
Create Proc Balance_Report (#AsOfDate)
AS
If #AsOfDate IS NULL or #AsOfDate = GetDate()
Exec Current_Balance_Date -- no param necessary
Else
exec MonthEnd_Balance_Date #AsOfDate
How you have things set up, the second method will probably be faster. If you were to use a partitioned view then you could set up constraints in such a way that the optimized would know to ignore one or more of the tables in the select and you would get the same performance. This would also let you keep all of your logic in one statement rather than having to keep two statements in sync. That may or may not be an issue for you based on how complex the SELECT statement is.
One thing to remember though, is that if you use the second method, be sure to mark your stored procedure as WITH (RECOMPILE) (I can't remember if the parentheses are require or not - check the syntax). That way the optimizer will create a new query plan based on which branch of the IF statement needs to be executed.
I prefer the non-union solution. Selecting from a single table will always be faster than doing a union and selecting a single table's data from the union.