I am new to T-SQL. What is the meaning of the following statement?
BEGIN
UPDATE table_name
SET a = ISNULL(#f_flag,0)
END
Begin, End: The Begin and End is not needed. It identifies a code
block, usefull if more that one statement.
UPDATE table_name: Update the data in the table "table_name".
SET: Keyword, start the comma delimited list of column - value pairs
to update
a = : a is the column mame, to value to the right of the = is what
value will be used
ISNULL(#f_flag,0): The value to assign. In this case the IsNull checks the value of the #f_flag variable, and if it is null, then use a 0.
*Note: that there is no "WHERE" clause here, therefore, all rows in the table will be updated.
Related
I have a Postgres function that accepts a text[] as input. For example
create function temp1(player_ids text[])
returns void
language plpgsql
as
$$
begin
update players set player_xp = 0
where id in (player_ids);
-- the body is actually 20 lines long, updating a lot of tables
end;
$$;
and I'm trying to call it, but I keep getting
[42883] ERROR: operator does not exist: text = text[] Hint: No operator matches the given name and argument types. You might need to add explicit type casts. Where: PL/pgSQL function temp1(text[]) line 3 at SQL statement
I have tried these so far
select temp1('{F7AWLJWYQ5BMPKGXLMDNQKQ4NY,AQPBAFKQONGLBKIMCSOD747GY4}');
select temp1('{F7AWLJWYQ5BMPKGXLMDNQKQ4NY,AQPBAFKQONGLBKIMCSOD747GY4}'::text[]);
select temp1(array['F7AWLJWYQ5BMPKGXLMDNQKQ4NY,AQPBAFKQONGLBKIMCSOD747GY4']);
select temp1(array['F7AWLJWYQ5BMPKGXLMDNQKQ4NY,AQPBAFKQONGLBKIMCSOD747GY4']::text[]);
I have to be missing something obvious...how do I call this function with an array literal?
Use = any instead of in:
...
update players set player_xp = 0
where id = any(player_ids);
...
The IN operator acts on an explicit list of values.
expression IN (value [, ...])
When you want to compare a value to each element of an array, use ANY instead.
expression operator ANY (array expression)
Note that there are variants of both constructs for subqueries expression IN (subquery) and expression operator ANY (subquery). The first one was properly used in the other answer though a subquery seems excessive in this case.
You can use unnest function, this function is very easy and same time best performanced. Unnest using for converting array elements to rows. Example:
create function temp1(player_ids text[])
returns void
language plpgsql
as
$$
begin
update players set player_xp = 0
where id in (select pl.id from unnest(player_ids) as pl(id));
-- the body is actually 20 lines long, updating a lot of tables
end;
$$;
And you can easily cast array elements to another type for using unnest.
Example:
update players set player_xp = 0
where id in (select pl.id::integer from unnest(player_ids) as pl(id));
I am trying to write a block of SQL code that compares two dates from two tables. One table shows when an item was acquired (ci_acquired_date). Another table shows when an item was an assigned to an employee (date_acquired). My goal is to use a loop that loops through the inventory and compare the dates and see if any of the dates assigned to an employee is less than the date the item was acquired (because it is impossible to assign an employee an item that was never bought) and use DBMS to show me which item ID it is and the dates it was acquired and assigned.
This is my code:
declare
cursor task_five is
select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER';
row_one jaherna42.employee_ci%rowtype;
row_two jaherna42.ci_inventory%rowtype;
begin
for row_one in task_five
loop
if(row_one.date_assigned < row_two.ci_acquired_date)
then
dbms_output.put_line('The error is: ' || row_one.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row_one.date_assigned);
dbms_output.put_line('The date acquired is: ' || row_two.ci_acquired_date);
end if;
end loop;
end;
When I run it, the script output box would show
PL/SQL procedure successfully completed.
But there would be nothing showing up in my dbms output box. What is the error?
row_two is a local variable that is declared but no value is ever assigned to it. Thus, every field in the record is always null. When you compare a value row_one.date_assigned against a null, the comparison will always evaluate to false. So your if statement is always false and nothing will ever be printed.
I'm a bit surprised that the code you posted compiles. row_one is declared as a jaherna42.employee_ci%rowtype but the query you've defined doesn't appear to return all the columns from employee_ci. Perhaps you're just lucky that the order and types of the columns in your table matches the order and types in your query even though that query pulls data from multiple tables. But that's a lucky accident.
If you want to keep the cursor in the declaration section, you'd almost certainly want your local variable to be declared against the cursor's %rowtype not the table's. So something like this is potentially what you're really after.
declare
cursor task_five
is
select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER';
row task_five%rowtype;
begin
for row in task_five
loop
if(row.date_assigned < row.ci_acquired_date)
then
dbms_output.put_line('The error is: ' || row.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row.date_assigned);
dbms_output.put_line('The date acquired is: ' || row.ci_acquired_date);
end if;
end loop;
end;
Unless it's a requirement of your assignment, though, it would probably make sense to avoid the declarations entirely and just use an implicit cursor in the code. And to do the comparison in SQL rather than PL/SQL
begin
for row in (select a.date_assigned, a.ci_inv_id, b.ci_acquired_date
from jaherna42.employee_ci a
join jaherna42.ci_inventory b
on a.ci_inv_id = b.ci_inv_id
where a.user_or_support = 'USER'
and a.date_assigned < b.ci_acquired_date)
loop
dbms_output.put_line('The error is: ' || row.ci_inv_id);
dbms_output.put_line('The date assigned is: ' || row.date_assigned);
dbms_output.put_line('The date acquired is: ' || row.ci_acquired_date);
end loop;
end;
I'd also generally suggest using meaningful aliases in your query. Aliasing tables to a and b is like using single character variable names-- unlikely to help someone reading the code understand what it is doing. It would almost certainly be more useful to use some consistent naming convention where, say, employee_ci is always aliased to emp and ci_inventory is always aliased to inv.
In my SQL Server stored procedure, I want to add a Where clause as dynamic as follows:
AND CASE WHEN #mySt <> '' THEN s.myStatus IN(#mySt) ELSE 0=0 END
When I want to check is: if #mySt is not empty, I want to add s.myStatus IN(#mySt).
If if #mySt is empty, I want to skip this where clause.
I get an error
Incorrect syntax near 'IN'
CASE is an expression, it returns a scalar value not a boolean result; you can't do want you're trying to do as s.myStatus IN(#mySt) isn't a scalar value.
Use proper boolean logic:
AND (s.myStatus = #mySt OR #mySt IS NULL) --I suggest NULL over a blank string
I replaced IN with =, as #mySt is a scalar value, so IN and = would be synonyms.
I need to check when function in MS SQL return empty string ('') in insert to table and handle condition. I don't know how. I use this syntax:
INSERT
INTO [DB].[dbo].[TablesNames]
(Name)
VALUES
(CASE
WHEN [dbo].Function(#ID, #ExternalName, #Level) IS ''
THEN #Name
ELSE [dbo].Function(#ID, #ExternalName, #Level))
How is correct syntax in this case? Thx for advance.
I would be more inclined to write this as:
INSERT INTO [DB].[dbo].[TablesNames](Name)
SELECT (CASE WHEN x = '' THEN #Name ELSE x END)
FROM (SELECT [dbo].Function(#ID, #ExternalName, #Level) as val) x;
Functions usually incur an overhead when they are called. This formulation gives SQL Server an opportunity to only evaluate the function once.
A couple more things:
I don't recognize IS. Might you mean IS NULL?
If you are looking at blank values (empty strings) do you also want to consider NULL values?
I need to execute a query that is highly dependent on several conditions what need to be checked by analyzing that data in other tables, the base goal is to return the rows from the tables if all of the conditions in the other tables are true, I am fed up with INNER joins LEFT joins and WHERE statement, i need to look up one table, if the returned value is 1, 0 or 4 or a set of values, i need to execute an other statement, and based on the resuts of that i need to execute one last statement which is my final result.
as far as functions are procedures are concerned, i studies the MySQL documentation like hell and all it gives me is this ::
DELIMITER $$
CREATE DEFINER=`root`#`localhost` FUNCTION `SimpleCompare`(n INT, m INT) RETURNS varchar(20) CHARSET latin1
BEGIN
DECLARE s VARCHAR(20);
IF n > m THEN SET s = '>';
ELSEIF n = m THEN SET s = '=';
ELSE SET s = '<';
END IF;
SET s = CONCAT(n, ' ', s, ' ', m);
RETURN s;
END
Now this is so plain, i dont even know where to start, I the "returns varchar(20)" what does it need to be if im expecting it to return a table of 10 rows and not a VARCHAR(20), what do I declare "DECLARE s VARCHAR(20);" as if i want it to be a table not a VARCHAR(20).
the (n > m) after the "IF" how to i replace it with my own query ,
and after I do that, the "THEN SET s = '>'" how do i set s = to the query results ?, this is driving me crazy the syntax is beyond me, and the documentation does not explain anything.
Thanks in advance
To my knowledge, MySQL doesn't support a table valued data type. The use of the function you posted would be:
SELECT simplecompare(yt.n, yt.m) AS eval
FROM YOUR_TABE yt
...which would return:
eval
--------
1 = 1
2 < 3
etc.
SQL is set based, which is different from typical programming (procedural or OO).