SQL*Loader: Use a field not in the table - oracle11g

Got an odd question, I'm trying to load some data into Oracle using SQL*loader.
The trick is, there is a field provided which I need to use as input to a user function to calculate another field. The original field I don't want to load.
I tried this: however, a FILLER field cannot be referenced as a BIND variable:
LOAD DATA
APPEND
INTO TABLE my_table
(
XREF_NUM FILLER POSITION(8:26),
ID_NUM POSITION(1:1) "my_func(:XREF_NUM)",
... other columns ...
)
Table defintion is just:
ID_NUM
COL1
COl2
but XREF_NUM does not exist in the table.
How do I set this up ?

Define it as BOUNDFILLER, which means treat it as a "remembered" FILLER. You can use it in expressions.
LOAD DATA
APPEND
INTO TABLE my_table
(
XREF_NUM BOUNDFILLER POSITION(8:26),
ID_NUM POSITION(1:1) "my_func(:XREF_NUM)",
... other columns ...
)

Related

Powerapps: Patch a record based on a text input control

I am wrestling with a simple patch function to update a record based off the value of an text input control. What I want is for PowerApps to update a record where a value in a table = the value in a text input field.
Table2 contains my data.
ID is unique for each row.
ProjID is the name of the text input control. This contains the value of ID that I want to update.
Current Phase is the column I want to update with the value in projID.
I have based the code below off some code which I use to create new records which works, so I think it is the lookup element that is not working.
Patch(
Table2,
lookup(Table2,Id = ProjID.Text ),
{
'Current Phase': CurrentPhase.Text,
}
)
)
Any help would be greatly appreciated!
The below should work and you can use comma either to add more conditions or data values
Patch( Table2,
First(Filter(Table2, ProjID.Text = Id ) )
, {
'Current Phase': CurrentPhase.Text
}
)

how to sanitize data in sqlite3 column

I have a sqlite3 table with a column by the name Title, which stores the names of the some movies.
Table name - table1
Column name - Title
Examples data: "Casablanca" (1983) {The Cashier and the Belly Dancer (#1.4)}
I have another sqlite3 table with a column that stores movie titles.
Table name - table2
Column name - Title
Examples data: casa blanca
Both these tables were created using different datasets, and as such although the movie name is the same (casa blanca vs "Casablanca" (1983) {The Cashier and the Belly Dancer (#1.4)}), both are stored with extra text.
What i would like to do is to SANITIZE the already stored data in both the columns. By sanitization, I would like to strip the cell content of:
1. spaces
2. spl chars like !, ', ", comma, etc..
3. convert all to lower case
I hope with that atleast some level of matching can be had between both the columns.
My question is, how do i perform these sanitizations on data that is already stored in sqlite tables. I do not have an option to sanitize before loading, as i only have access to the loaded database.
I am using sqlite 3.7.13, and i am using sqlite manager as the gui.
Thank You.
This task is too specialized to be done in SQL only.
You should write simple Perl or Python script which will scan your table, read data row by row, scrub it to meet your requirements and write it back.
This is example in Perl:
use DBI;
my $dbh = DBI->connect("dbi:mysql:database=my.db");
# replace rowid with your primary key, but it should work as is:
my $sth = $dbh->prepare(qq{
SELECT rowid,*
FROM table1
});
while (my $row = $sth->fetchrow_hashref()) {
my $rowid = $row->{rowid};
my $title = $row->{title};
# sanitize title:
$title = lc($title); # convert to lowercase
$title =~ s/,//g; # remove commas
# do more sanitization as you wish
# ...
# write it back to database:
$dbh->do(
qq{
UPDATE table1
SET title = ?
WHERE rowid = ?
}, undef,
$title,
$rowid,
);
}
$sth->finish();
$dbh->disconnect();

MySQL Changing Order Depending On Contents of a Column

I have a MySQL table Page with 2 columns: PageID and OrderByMethod.
I also then have a Data table with lots of columns including PageID (the Page the data is on), DataName, and DataDate.
I want OrderByMethod to have one of three entries: Most Recent Data First, Most Recent Data Last, and Alphabetically.
Is there a way for me to tack an "ORDER BY" clause to the end of this query that will vary its ordering method based on the contents of the "OrderByMethod" column? For example, in this query, I would want to have the ORDER BY clause contain whatever ordering rule is stored in Page 1's OrderByMethod column.
GET * FROM `Data` WHERE `Data`.`PageID`=1 ORDER BY xxxxxx;
Maybe a SELECT clause in the ORDER BY clause? I'm not sure how that would work though.
Thanks!
select Data.*
from Data
inner join Page on (Data.PageID=Page.PageID)
where Data.PageID=1
order by
if(Page.OrderByMethod='Most Recent Data First', now()-DataDate,
if(Page.OrderByMethod='Most Recent Data Last', DataDate-now(), DataName)
);
You can probably do this with the IF syntax to generate a column that you can then order by.
SELECT *, IF(Page.OrderBy = 'Alphabetically', Data.DataName, IF(Page.OrderBy = 'Most Recent Data First', NOW() - Data.DataDate, Data.DataDate - NOW())) AS OrderColumn
FROM Data
INNER JOIN Page ON Data.PageID = Page.PageID
WHERE Page.PageID = 1
ORDER BY OrderColumn
The direction of the ordering is determined in the calculation of the data instead of specifying a direction in the ORDER BY
Can you just append the order by clause to the select statement and rebind the table on postback?
If you want to use the content of the column in Page table as an expression in ORDER BY you have to do it using prepared statements. Let say, you store in OrderByMethod something like "field1 DESC, field2 ASC" and you want this string to be used as it is:
SET #order_by =(SELECT OrderByMethod FROM Page WHERE id = [value]);
SET #qr = CONCAT(your original query,' ORDER BY ', #order_by);
PREPARE stmt FROM #qr;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
If you want the result set to be sorted based on the value of OrderByMethod , you can use IF as it was already mentioned by others, or CASE :
...
ORDER BY
CASE OrderByMethod
WHEN 'val1' THEN field_name1
WHEN 'val2' THEN field_name2
....etc
END

In query in SQLite

"IN" query is not working. Please guide me if i am wrong.
KaizenResultsInformationTable is MasterTable having field "recordinfo", this field contains Child table Ids as string.
kaizenResultsRecordInformationTable is Childtable having field "recordId".
I have to match records of child.
Query:
select recordinfo from KaizenResultsInformationTable
Output: ;0;1;2;3;4;5;6;7;8;9;10
Query:
select substr(replace(recordinfo,';','","'),3,length(recordinfo))
from KaizenResultsInformationTable`
Output: "0","1","2","3","4","5"
This query is not working:
select * from kaizenResultsRecordInformationTable
where substr(recordid,0,2) in (
select substr(replace(recordinfo,';','","'),3,length(recordinfo))
from KaizenResultsInformationTable
)
This query is working:
select * from kaizenResultsRecordInformationTable
where substr(recordid,0,2) in ("0","1","2","3","4","5")
You can't use in like that. In your second query, you are passing in a single string containing a comma-separated list of values.
It is better to represent a list of IDs as one record for each value.
Also, I'm not sure why you are taking a substring of your recordid. You should usually be storing one value per column.
However, if you can't change the schema, you can use string matching with 'like' instead of 'in'. Something like this should work:
select a.* from kaizenResultsRecordInformationTable a
join KaizenResultsInformationTable b
on (';'+b.recordinfo+';') LIKE ('%;'+trim(substr(recordid,0,2))+';%')
So if your recordinfo looks like 1;2;3;4;5;6, and your substr(recordid,0,2) looks like 1, this will include that row if ";1;2;3;4;5;6;" LIKE "%;1;%", which is true.

How to handle a missing feature of SQLite : disable triggers?

How to handle a missing feature of SQLite: disable triggers?
I don't have it stored the name of triggers for a specific table.
For example how can I drop all triggers?
What would you do?
So here it is 2015 and there still is no 'disable triggers' in SQLite. For a mobile Application this can be problematic--especially if it's a corporate App requiring offline functionality and local data.
An initial data load can be slowed to crawl by trigger execution even when you don't wrap each insert in an individual transaction.
I solved this issue using SQLite SQL fairly simply. I have a settings table that doesn't participate in the init load. It holds 'list' of key/value pairs. I have one key called 'fireTrigger' with a bit value of 0 or 1. Every trigger I have has an expression that selects value and if it equals 1 it fires the trigger, otherwise it doesn't.
This expression is in addition to any expressions evaluated on the data relating to the trigger. e.g.:
AND 1 = (SELECT val FROM MTSSettings WHERE key = 'fireTrigger')
In simple clean effect this allows me to disable/enable the trigger with a simple UPDATE to the settings table
I wrote a very simple extension function to set a boolean value to true or false.
And a function to retrieve this value (GetAllTriggersOn()).
With this function I can define all my triggers like:
CREATE TRIGGER tr_table1_update AFTER UPDATE ON TABLE1 WHEN GetAllTriggersOn()
BEGIN
-- ...
END
SQLite stores schema (meta) information in the built-in sqlite_master table.
To get a list of available triggers use the below query:
SELECT name FROM sqlite_master
WHERE type = 'trigger' -- AND tbl_name = 'a_table_name'
Set a flag in your database and use it in the triggers WHEN condition.
Say you want to create a trigger on the "clients" table after an insert. You have created a table "trigger_settings" with a TINYINT "triggers_on" field - this is your flag. Then you can set the field to 0 if you want to turn off the filters and to 1 when you want to turn them back on.
Then you create your filter with a WHEN condition that checks the "triggers_on" field.
For example:
CREATE TRIGGER IF NOT EXISTS log_client_data_after_insert
AFTER INSERT
ON [clients]
WHEN (SELECT triggers_on FROM trigger_settings)=1
BEGIN
your_statement
END;
Maybe you can make a stored procedures for droping and creating them. Is that good for you ?
Expanding on Nick Dandoulakis's answer, you could drop all relevant triggers and then reinstate them before the transaction's completion:
BEGIN;
SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND tbl_name = 'mytable';
-- store all results
-- for each name: DROP TRIGGER $name;
-- do normal work
-- for each sql: execute the SQL verbatim
COMMIT;
Expanding other answers this is how i'm doing it. Take into account that this is disabling all triggers for all tables in the database except some of then used by spatialite
SQLITE_FILE=/tmp/my.sqlite
# Define output sql files as variables
CREATE_TRIGGER_SQL=/tmp/create_triggers.sql
DROP_TRIGGER_SQL=/tmp/drop_triggers.sql
## Dump CREATE TRIGGER statements to a file ##
# To wrap statements in a transaction
echo -e "BEGIN;\n\n" > "${CREATE_TRIGGER_SQL}"
# `SELECT sql` does not output semicolons, so we must concatenate them
sqlite3 -bail "${SQLITE_FILE}" "SELECT sql || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${CREATE_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${CREATE_TRIGGER_SQL}"
## Dump DROP TRIGGER statements to a file ##
echo -e "BEGIN;\n\n" > "${DROP_TRIGGER_SQL}"
sqlite3 -bail "${SQLITE_FILE}" "SELECT 'DROP TRIGGER ' || name || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${DROP_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${DROP_TRIGGER_SQL}"
## Execute like ##
sqlite3 -bail /"${SQLITE_FILE}" < "${DROP_TRIGGER_SQL}"
# do things
sqlite3 -bail /"${SQLITE_FILE}" < "${CREATE_TRIGGER_SQL}"

Resources