How to pass computed value for column1 onto column2 in update - plsql

First of all, I am using plsql, and adapting an existing command. I probably would have done it differently from scratch.
I want to do something of this kind, but this doesn't work.
UPDATE TABLE_NAME
SET COLUMN1 = FUNCTION1(...)
, COLUMN2 = FUNCTION2(..., COLUMN1)
;
Ideally, I would like to avoid doing this
UPDATE TABLE_NAME
SET COLUMN1 = FUNCTION1(...)
, COLUMN2 = FUNCTION2(..., FUNCTION1(...))
;
Is there any way of achieving this, maybe by storing the computed value for COLUMN1 into a variable?
For example, in C, something like this would be possible.
COLUMN1 = VARIABLE_NAME = FUNCTION1(...)
Or maybe by positionally referring to it? This syntax doesn't work, but I have a vague idea that it might be possible.
UPDATE TABLE_NAME
SET COLUMN1 = FUNCTION1(...)
, COLUMN2 = FUNCTION2(..., {1})
;
Thanks.

If you are doing this in PL/SQL then you can call the functions, assigned the return value to variables and then use those variables to update the table. Like:
lv_col1 := function1(...);
lv_col2 := function2(...,lv_col1);
update table
set column1 = lv_col1,
column2 = lv_col2
This way you don't have to call the function1 multiple times.

Related

SQLITE UPDATE query replicating rows

I have an update query that when I run it instead of matching each unique row it is replicating the same row through the entire column.
Any help would be massively appreciated.
I have got
UPDATE Table1
SET Column1 = (SELECT Column1 FROM [Table2] WHERE Column2 = [Table2].Column2)
[Table2].Column2 referes to the column in Table2.
Column2 refers to the column in some table that has such a column. The innermost such table is Table2.
So this ends up being the same as Table2.Column2 = Table2.Column2.
To refer to the column in Table1, specify that table:
UPDATE Table1
SET Column1 = (SELECT Column1
FROM Table2
WHERE Table2.Column2 = Table1.Column2);

Query to Replace a value with a different value in a table

I would like to replace a value Test to Mess in Column A in a table T where the value is Var in Column B in the same table.
Please someone help me with the query as I'm new to Oracle.
This is very easy, try this:
UPDATE t
SET A = REPLACE(A, 'Test', 'Mess')
WHERE B = 'Var';
or if You want not replace, but full text update in A column, you can make like this :
UPDATE t
SET A = 'Mess'
WHERE B = 'Var' and A = 'Test';

How to set unique constraint over multiple columns when any one can be null?

How do I set unique constraint over multiple columns when any one can be null in SQLite?
e.g. I have made unique("col1","col2","col3") and tried insert into tablename values("abc","def",null) twice it inserted both rows.
The unique constraint is not working when third column is null.
In sqlite, all null are differences.
I think the best way to solve this issue is to set column c not null with a special default value. Then use the default value (for example 0, '') to represent null.
edit 1
you can easily extend this solution to any columns
create table test (
a text not null default "",
b text not null default "",
c text not null default ""
);
You could create a trigger to enfore this:
CREATE TRIGGER col1_col2_col3null_unique
BEFORE INSERT ON MyTable
FOR EACH ROW
WHEN col1 IS NOT NULL
AND col2 IS NOT NULL
AND col3 IS NULL
BEGIN
SELECT RAISE(ABORT, 'col1/col2/col3 must be unique')
FROM MyTable
WHERE col1 = NEW.col1
AND col2 = NEW.col2
AND col3 IS NULL;
END;
You need such a trigger for each possible combination of NULLs in the three columns.
Furthermore, if it is possible to have UPDATEs that change such a column to NULL, you need triggers for those, too.
Starting with version 3.9.0 (2015-10-14) you can use indexes on expressions (https://www.sqlite.org/expridx.html) and use for example the COALESCE function to transform null values into some form of fallback value:
CREATE UNIQUE INDEX IX_Unique ON Table1 (
COALESCE(col1, ""),
COALESCE(col2, ""),
COALESCE(col3, "")
);

sqlite - how do I get a one row result back? (luaSQLite3)

How can I get a single row result (e.g. in form of a table/array) back from a sql statement. Using Lua Sqlite (LuaSQLite3). For example this one:
SELECT * FROM sqlite_master WHERE name ='myTable';
So far I note:
using "nrows"/"rows" it gives an iterator back
using "exec" it doesn't seem to give a result back(?)
Specific questions are then:
Q1 - How to get a single row (say first row) result back?
Q2 - How to get row count? (e.g. num_rows_returned = db:XXXX(sql))
In order to get a single row use the db:first_row method. Like so.
row = db:first_row("SELECT `id` FROM `table`")
print(row.id)
In order to get the row count use the SQL COUNT statement. Like so.
row = db:first_row("SELECT COUNT(`id`) AS count FROM `table`")
print(row.count)
EDIT: Ah, sorry for that. Here are some methods that should work.
You can also use db:nrows. Like so.
rows = db:nrows("SELECT `id` FROM `table`")
row = rows[1]
print(row.id)
We can also modify this to get the number of rows.
rows = db:nrows("SELECT COUNT(`id`) AS count FROM `table`")
row = rows[1]
print(row.count)
Here is a demo of getting the returned count:
> require "lsqlite3"
> db = sqlite3.open":memory:"
> db:exec "create table foo (x,y,z);"
> for x in db:urows "select count(*) from foo" do print(x) end
0
> db:exec "insert into foo values (10,11,12);"
> for x in db:urows "select count(*) from foo" do print(x) end
1
>
Just loop over the iterator you get back from the rows or whichever function you use. Except you put a break at the end, so you only iterate once.
Getting the count is all about using SQL. You compute it with the SELECT statement:
SELECT count(*) FROM ...
This will return one row containing a single value: the number of rows in the query.
This is similar to what I'm using in my project and works well for me.
local query = "SELECT content FROM playerData WHERE name = 'myTable' LIMIT 1"
local queryResultTable = {}
local queryFunction = function(userData, numberOfColumns, columnValues, columnTitles)
for i = 1, numberOfColumns do
queryResultTable[columnTitles[i]] = columnValues[i]
end
end
db:exec(query, queryFunction)
for k,v in pairs(queryResultTable) do
print(k,v)
end
You can even concatenate values into the query to place inside a generic method/function.
local query = "SELECT * FROM ZQuestionTable WHERE ConceptNumber = "..conceptNumber.." AND QuestionNumber = "..questionNumber.." LIMIT 1"

Copy a subset of column data from one table to another

I have two tables with identical schema. Let's name them TestTable and TestTableTemp. I need to copy just two columns from TestTableTemp to TestTable without disrupting other data. The rows in TestTable are a subset of those in TestTableTemp. Let's say the columns that I need to copy are named Column1 and Column2 and that they have identical primary keys reference by column primaryKey.
In mysql I believe this could be done as such or something similar:
UPDATE TestTable, TestTableTemp
SET TestTable.Column1 = TestTableTemp.Column1, TestTable.Column2 = TestTableTemp.Column2
WHERE TestTable.primaryKey = TestTableTemp.primaryKey
Sqlite does not allow for multiple tables to be defined on the update statement as can been seen in their reference data here: http://www.sqlite.org/lang_update.html
The best I could come up with is such:
UPDATE TestTable SET
Column1 = (select TestTableTemp.Column1 from TestTableTemp, TestTable where TestTable.primaryKey = TestTableTemp.primaryKey),
Column2 = (select TestTableTemp.Column2 from TestTableTemp, TestTable where TestTable.primaryKey = TestTableTemp.primaryKey)
WHERE EXISTS(select * from TestTableTemp where TestTable.primaryKey = TestTableTemp.primaryKey"
This gives me a syntax error near "." I am guessing this is because I cannot reference TestTable in the scalar expressions.
Can anyone point me in the right direction? Any help is much appreciated.
EDIT:
I cleaned up the second query a bit. It seems to just set the Column1 and Column2 to the first row from that column from TestTableTemp.
Your original query for comparison:
UPDATE TestTable, TestTableTemp
SET TestTable.Column1 = TestTableTemp.Column1
, TestTable.Column2 = TestTableTemp.Column2
WHERE TestTable.primaryKey = TestTableTemp.primaryKey
Here is the working query (I just slightly changed your version):
http://sqlfiddle.com/#!5/f3a19/9
UPDATE TestTable
SET
Column1 = ( SELECT TestTableTemp.Column1
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
,Column2 = ( SELECT TestTableTemp.Column2
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
WHERE EXISTS( SELECT NULL
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
;

Resources