I have created a view using 2 columns from my Employee table like this
Create VIEW [dbo].[vwTestEmp] AS
select
EMpID,
case when (Address1 IS null) then null
when (Address1 IS not null) then Address1
end as "EMpAddress",
'' as "Date_Verified"
FROM Employee;
Now Date_Verified is not in the Employee table, so is a derived column in the view and contains null. After manual verification of certain processes, I want to call
update [dbo].[vwTestEmp]
set Date_verified = GETDATE()
where EMpid = 60;
I am getting an error
Update or insert of view or function 'vwTestEMp' failed because it contains a derived or constant field.
How to handle this error?
THanks
MR
You cannot update the view through the constant value for Date_Verified. Change the query to:
CREATE VIEW [dbo].[vwTestEmp1] AS
SELECT EMpID, Address1 AS EMpAddress], [Date_Verified]
FROM EMployee;
This avoids the unnecessary CASE and replaces the constant value for the date column with the underlying column.
This updates as shown in the SqlFiddle.
You have an error. The correct syntax is:
UPDATE < view_name > SET<column1>=<value1>,<column2>=<value2>,... WHERE <condition>;
Use a table.
select
EMpID,
Address1 as "EMpAddress",
'' as "Date_Verified"
INTO [dbo].[tblTestEmp]
FROM Employee;
update [dbo].[tblTestEmp]
set Date_verified = GETDATE()
where EMpid = 60;
Related
view in snowflake as follows;
CREATE OR REPLACE VIEW A AS(
SELECT tab1.colA,
tab1.colB,
CASE WHEN COALESCE(DATE_ACT_CREATED,'missing')='missing' THEN DATE ('1970-01- 01') ELSE TO_DATE(DATE_ACT_CREATED) END AS ACT_CREATED_DATE
FROM tab1);
Please note that because of some reasons, column DATE_ACT_CREATED was defined as varchar earlier. This view is created fine. But when I try to retrieve records from it;
SELECT * FROM viewA;
I get following error,
Date '' is not recognized
But when I take out the entry; CASE WHEN COALESCE(DATE_ACT_CREATED,'missing')='missing' THEN DATE ('1970-01- 01') ELSE TO_DATE(DATE_ACT_CREATED) END AS ACT_CREATED_DATE the error is gone.
May I know how can I handle this date error issue? Found this link enter link description here, but it couldn't help much.
Help is appreciated.
You get the error because the case when DATE_ACT_CREATED is an empty string is not handled in your CASE condition. So the TO_DATE function couldn't work.
You should try TRY_TO_DATE. If your entry couldn't be casted as a date then it returns null that will be handled with your COALESCE.
CREATE OR REPLACE viewA AS(
SELECT
tab1.colA,
tab1.colB,
COALESCE(TRY_TO_DATE(DATE_ACT_CREATED), DATE('1970-01- 01')) AS ACT_CREATED_DATE
FROM tab1);
Using the following query you will not get the error if the input is ''(Empty string), actual date, NULL keyword, or missing keyword.
CREATE OR REPLACE VIEW A
AS
SELECT COL1, COL2,
CASE WHEN COALESCE(DATE_AT_CREATED, '') = '' THEN DATE('1970-01-02')
ELSE CASE WHEN DATE_AT_CREATED = 'missing' THEN DATE('1970-01-02') ELSE TO_DATE(DATE_AT_CREATED) END
END AS ACT_CREATED_DATE
FROM TAB1;
SELECT * FROM A;
I'd like to update fields while referring to a dynamic column.
The goal is to automate a process because each month the column to refer to changes.
For example it's like having different columns like month1, month2, month3 until month24. Each month, only 1 column needs to be updated but it's a running number that is calculated in another table.
So my question is how to make the query dynamic so that every month i only update the column number that i want and not the other one.
I tried the script below but the following issue comes up
Error converting data type varchar to float.
DECLARE #PromoMonthNumber VARCHAR(60)
DECLARE #PromoMonth VARCHAR(600)
SET #PromoMonthNumber = (SELECT CurrentDemandIndex FROM RidgeSys) --This refer to a number that change all the time
SET #PromoMonth = 'SELECT ABC.PromotionHistory' + #PromoMonthNumber
UPDATE ABC
SET #PromoMonth = table2.promotionhistory
FROM ABC
INNER JOIN (
SELECT Article.code as code, sum(ROUND(#PromoMonth,0)) as promotionhistory
FROM Article
INNER JOIN ABC ON DEF.articlecode = ABC.Articlecode
) as table2
ON ABC.articlecode = table2.code)
Here is your issue:
SELECT Article.code as code, sum(ROUND(#PromoMonth,0)) as promotionhistory
Since #PromoMonth is defined as VARCHAR, if the value is non-numeric, it will fail. Here is an example:
This works fine:
declare #x varchar(100) = '1';
select sum(round(#x,0));
Result:
1
This fails with same error above:
declare #x varchar(100) = 'x';
select sum(round(#x,0));
Result:
Msg 8114, Level 16, State 5, Line 3
Error converting data type varchar to float.
You need to check that the value is numeric before you do the calculation.
I'm trying to add this as a Formula (Computed Column) but I'm getting an error message saying it is not valid.
Can anyone see what is wrong with the below formula?
IIF
(
select * from Config where Property = 'AutomaticExpiry' and Value = 1,
case when [ExpiryDate] IS NULL OR sysdatetimeoffset()<[ExpiryDate] then 1 else 0 end,
case when [ExpiryDate] IS NULL then 1 else 0 end
)
From BOL: ALTER TABLE computed_column_definition
computed_column_expression Is an expression that defines the value of
a computed column. A computed column is a virtual column that is not
physically stored in the table but is computed from an expression that
uses other columns in the same table. For example, a computed column
could have the definition: cost AS price * qty. The expression can be
a noncomputed column name, constant, function, variable, and any
combination of these connected by one or more operators. The
expression cannot be a subquery or include an alias data type.
Wrap the login in function. Something like this:
CREATE FUNCTION [dbo].[fn_CustomFunction]
(
#ExpireDate DATETIME2
)
RETURNS BIT
AS
BEGIN;
DECLARE #Value BIT = 0;
IF EXISTS(select * from Config where Property = 'AutomaticExpiry' and Value = 1)
BEGIN;
SET #Value = IIF (sysdatetimeoffset()< #ExpireDate, 1, 0)
RETURN #value;
END;
RETURN IIF(#ExpireDate IS NULL, 1, 0);
END;
GO
--DROP TABLE IF EXISTS dbo.TEST;
CREATE TABLE dbo.TEST
(
[ID] INT IDENTITY(1,1)
,[ExpireDate] DATETIME2
,ComputeColumn AS [dbo].[fn_CustomFunction] ([ExpireDate])
)
GO
INSERT INTO dbo.TEst (ExpireDate)
VALUES ('2019-01-01')
,('2018-01-01')
,(NULL);
SELECT *
FROM dbo.Test;
Youre trying to do something, what we're not quite sure - you've made a classic XY problem mistake.. You have some task, like "implement auto login expiry if it's on in the prefs table" and you've devised this broken solution (use a computed column/IIF) and have sought help to know why it's broken.. It's not solving the actual core problem.
In transitioning from your current state to one where you're solving the problem, you can consider:
As a view:
CREATE VIEW yourtable_withexpiry AS
SELECT
*,
CASE WHEN [ExpiryDate] IS NULL OR config.[Value] = 1 AND SysDateTimeOffset() < [ExpiryDate] THEN 1 ELSE 0 END AS IsValid
FROM
yourtable
LEFT JOIN
config
ON config.property = 'AutomaticExpiry'
As a trigger:
CREATE TRIGGER trg_withexpiry ON yourtable
AFTER INSERT OR UPDATE
AS
IF NOT EXISTS(select * from Config where Property = 'AutomaticExpiry' and Value = 1)
RETURN;
UPDATE yourtable SET [ExpiryDate] = DATE_ADD(..some current time and suitable offset here..)
FROM yourtable y INNER JOIN inserted i ON y.pk = i.pk;
END;
But honestly, you should be doing this in your front end app. It should be responsible for reading/writing session data and keeping things up to date and kicking users out if they're over time etc.. Using the database for this is, to a large extent, putting business logic/decision processing into a system that shouldn't be concerned with it..
Have your front end language implement a code that looks up user info upon some regular event (like page navigation or other activity) and refreshes the expiry date as a consequence of the activity, only if the expiry date isn't passed. For sure too keep the thing valid if the expiry is set to null if you want a way to have people active forever (or whatever)
I couldn't even think of how to phrase this properly for the title.
I have an SSRS report with a multi-valued parameter called Department.
If the user IS IN Department A..We want to default to all departments EXCEPT department A
If the user IS NOT IN Department A..We want to default to only their department
Department A will never be in the parameter list but being a member of department A impacts what you will see.
I know that I could resolve this with an ALL parameter option, but I would prefer the only parameter values to be valid department names
My parameter is populated with two datasets.
The first dataset has three options for valid departments: EUR, REM, LIFA
The second dataset only determines the current user's department and would populate the default. IF the current user's department is CS we want to select the other three departments as the default. If their department <> CS we want to default to only their department.
I thought the code below would work but the concatenated string is not an option in the first dataset so it cannot be the default option
SELECT DISTINCT
CASE
WHEN EmployeePracticeArea = 'CS'
THEN 'EUR, LIFA, REM'
ELSE EmployeePracticeArea
END AS 'EmployeePracticeArea'
FROM DimEmployee
WHERE
(EmployeePracticeArea <> '')
AND (UserLogin = #CurrentUser)
The problem with the case statement is that it tries to set a default value of EUR, LIFA, REM. This string does not exist in the 'options' list of values. The options are the three seperate strings EUR, LIFA, REM.
Case statements cannot return multiple values so I need to evaluate the current user's department and then return a list without it
Here is something which will generate the dataset for you
IF OBJECT_ID('tempdb..#TestData') IS NOT NULL
DROP TABLE #TestData;
WITH Data (EmployeePracticeArea) AS (
SELECT 'LIFA'
UNION
SELECT 'REM'
UNION
SELECT 'EUR'
UNION
SELECT 'CS'
)
SELECT * INTO #TestData FROM Data ;
The end result is like this:
User1 in the LIFA department has his parameter defaulted to just LIFA
User2 in the CS department has his parameter defaulted to EUR, LIFA, REM
DECLARE #t TABLE(Dept varchar(4))
DECLARE #CurrentUserDept varchar(4) = (SELECT EmployeePracticeArea FROM dimEmployee WHERE UserLogin = #CurrentUser)
IF #CurrentUserDept = 'CS'
BEGIN
INSERT INTO #t VALUES ('EUR'), ('LIFA'), ('REM')
END
ELSE
BEGIN
INSERT INTO #t SELECT #CurrentUserDept
END
SELECT * FROM #t
In order to build a statistical report, i need to execute this kind of request, for each 5000 agencies, and each 5 state, so 25 000 requests :
select count(*) from transaction where state == 1 and where id_agency==1;
select avg(duration) from transaction where state == 1 and where id_agency==1;
How to build a stored procedure which gathers all the results of these requests, into one list key-value ?
CountAgency1CountState1 = 123;
CountAgency2CountState5 = 645;
CountAgency8AverageState7 = 987;
Data Table structure : 2 tables :
Table Transaction : id_transac, duration, state, idAgency
Table Agency : idAgency, adress, city
It seems like what you need is to group by ID and State
SELECT ID_Agency
,State
,Count(*) [ID_Count]
,AVG(Duration) [Avg_Duration]
FROM Transaction
group by ID_Agency
,State
This will give you one row per ID and State with the 2 values you need.
actually by assuming your data we can proceed by using AVG() and GROUP BY to get count basing on ID .it's example if you provide exact data we can get some more accurate output
CREATE table #T(ID INT,Value INT)
INSERT INTO #T (ID,Value)values (1,10),(1,20),(1,30),(2,10),(2,20),(2,30)
GO
CREATE PROCEDURE Getaverage
(#i_id INT)
AS
BEGIN
select DISTINCT COUNT(ID) ,AVG(value),SUM(VALUE) from #T t
WHERE (t.id = #i_id OR #i_id IS NULL)
GROUP BY ID
END
Why not do it all in the one query?
SELECT 'CountAgency' +
CAST(idAgency as varchar) +
'CountState' +
CAST(state as varchar) As Name
,CountAgency
,AvgDuration
FROM (
SELECT idAgency
,state
,COUNT(*) As CountAgency
,AVG(T.Duration) As AvgDuration
FROM [Transaction]
GROUP BY idAgency, state
) InnerQuery