Teradata fastload column length overflow - teradata

Error on piom GET ROW: 60, Text: Column length error, row
not returned !ERROR! Delimited Data Parsing error: Column
length overflow(s) in row 2 for column 1
Sample CSV file that I am attempting to load, along with the fld script is listed below.
"zip1","zip2"
"00601","00631"
"00601","00641"
"00601","00624"
"00601","00731"
"00601","00656"
"00601","00669"
"00601","00664"
"00601","00698"
"00601","00606"
.sessions 2;
ERRLIMIT 40;
.logmech ldap;
.LOGON dummyip.com / dummyuser,pass;
DATABASE DUMMY_DB;
.set record vartext ",";
DROP TABLE ZIP_DISTANCE;
DROP TABLE ZIP_DISTANCE_ERROR1;
DROP TABLE ZIP_DISTANCE_ERROR2;
CREATE SET TABLE ZIP_DISTANCE
(
zip1 VARCHAR(5),
zip2 VARCHAR(5)
)
PRIMARY INDEX ZIP_DISTANCE(zip1, zip2);
RECORD 2;
DEFINE
zip1 (varchar(5)),
zip2 (varchar(5))
FILE="C:\Users\dummyuser\Downloads\gaz2016zcta5distancemiles.csv";
BEGIN LOADING
ZIP_DISTANCE
errorfiles
ZIP_DISTANCE_ERROR1,
ZIP_DISTANCE_ERROR2
CHECKPOINT 5;
INSERT INTO ZIP_DISTANCE
(
ZIP1,
ZIP2
)
VALUES
(
:zip1,
:zip2
);
END LOADING;
.LOGOFF;

Related

Dynamic Column Update PLSQL trigger

I have two tables A and B
In table A there are two columns "Sequence Number" and "Content".
Name Null? Type
------- ----- ------------
SEQ_NO NUMBER(6)
CONTENT VARCHAR2(20)
In table B there are multiple statement columns like "Stmt_1", "Stmt_2", "Stmt_3" etc.
Name Null? Type
------ ----- ------------
STMT_1 VARCHAR2(20)
STMT_2 VARCHAR2(20)
STMT_3 VARCHAR2(20)
STMT_4 VARCHAR2(20)
I want to create a trigger on table A such that after every insert on table A, according to the "Sequence Number" value the corresponding column in table B gets updated.
For example: If table A has "Sequence Number" = 1 , then "Stmt_1" of table B gets updated to the value of "Content" column in table A.
If table A is given as
"SEQ_NO" "CONTENT"
1 "This is Content"
Then Table B should look like:
"STMT_1","STMT_2","STMT_3","STMT_4"
"This is Content","","",""
My approach is as follows:
create or replace trigger TestTrig
after insert on A for each row
begin
declare
temp varchar2(6);
begin
temp := concat("Stmt_",:new.seq_no);
update B
set temp = :new.content;
end;
end;
But I am getting an error in the update statement.
Does anyone know how to approach this problem?
You need to use dynamic SQL (and ' is for string literals, " is for identifiers):
create or replace trigger TestTrig
after insert on A
for each row
DECLARE
temp varchar2(11);
begin
temp := 'Stmt_' || TO_CHAR(:new.seq_no, 'FM999990');
EXECUTE IMMEDIATE 'UPDATE B SET ' || temp || ' = :1' USING :NEW.content;
end;
/
You probably want to handle errors when seq_no is input as 5 and there is no STMT_5 column in table B:
create or replace trigger TestTrig
after insert on A
for each row
DECLARE
temp varchar2(11);
INVALID_IDENTIFIER EXCEPTION;
PRAGMA EXCEPTION_INIT(INVALID_IDENTIFIER, -904);
begin
temp := 'Stmt_' || TO_CHAR(:new.seq_no, 'FM999990');
EXECUTE IMMEDIATE 'UPDATE B SET ' || temp || ' = :1' USING :NEW.content;
EXCEPTION
WHEN INVALID_IDENTIFIER THEN
NULL;
end;
/
However
I would suggest that you do not want a table B or a trigger to update it and you want a VIEW instead:
CREATE VIEW B (stmt_1, stmt2, stmt3, stmt4) AS
SELECT *
FROM A
PIVOT (
MAX(content)
FOR seq_no IN (
1 AS stmt_1,
2 AS stmt_2,
3 AS stmt_3,
4 AS stmt_4
)
);
fiddle;

SQLite insert select result multiple times

I have a database with three tables 'contacts', 'names', and 'contact_names'.
create table contacts(id integer, gid integer, sid integer);
create table names(id integer primary key, name text);
create table contact_names(fullname text);
insert into names(name) values ('Eberhard');
insert into names(name) values ('Esche');
insert into contacts values(1, (select id from names where name='Eberhard'), (select id from names where name='Esche'));
Now I want to insert the pair 'given name+surname' twice, once as 'given name+surname' and once as 'surname+given name'. What I currently have is a statment like this to generate these names:
SELECT gTable.name || ' ' || sTable.name AS name1, sTable.name || ' ' || gTable.name AS name2 FROM
(
SELECT name FROM names WHERE id=2
) AS gTable,
(
SELECT name FROM names WHERE id=1
) AS sTable;
What I am not able to perform is to insert these names now to table 'contact_names' using something like this:
INSERT INTO contact_names VALUES (name1), (name2) WITH
SELECT gTable.name || ' ' || sTable.name AS name1, sTable.name || ' ' || gTable.name AS name2 FROM
(
SELECT name FROM names WHERE id=2
) AS gTable,
(
SELECT name FROM names WHERE id=1
) AS sTable;
As result table 'contact_names' shall contain the two entries (rows) "Esche Eberhard" and "Eberhard Esche". Does anyone have a clue how to achieve this? Of course I could do the select statement twice, but I would prefer to do this with one select.
BR, Udo
PS: Maybe it is useful to explain why I want to do that. The INSERT statement for 'contact_names' shall be performed by a trigger that is called on removal of entries from 'contacts'. If I remove a row for instance with
DELETE FROM contacts WHERE id=1;
then the two name combination of that contact shall be inserted into 'contact_names' (for further handling of these names). The table will be cleared regularily after handling the removed names.
You have one row with two columns, but you want two rows with one column.
In the general case, this can be done with a common table expression and a compound query:
WITH TwoColumns(a, b) AS (
SELECT a, b FROM ... -- the original two-column query
)
INSERT INTO ...(x)
SELECT a FROM TwoColumns
UNION ALL
SELECT b FROM TwoColumns;
In this case, we don't need so many subqueries and can simplify a little:
WITH gs(gName, sName) AS (
SELECT g.name,
s.name
FROM names AS g,
names AS s
WHERE g.id = 2
AND s.id = 1
)
INSERT INTO contact_names(fullname)
SELECT gName || ' ' || sName FROM gs
UNION ALL
SELECT sName || ' ' || gName FROM gs;

How to use set rowcount in select query

I have a select query statement which will result 600k rows. When I blindly extract the result using select statement it will impact db performance. Is there an option to use Set rowcount for fetching the data? I tried the below code but it keep on resulting top 50000 rows and ended up in infinite loop.
#!/bin/ksh -x
trap "" 1
updrowcount=50000
while [ $updrowcount -eq 50000 ]
do
QUERY="set rowcount 50000
select subject into tempdb..extract from tablename where fldr_id=8"
runisql <<EOF > db_restenter code here
$QUERY
goenter code here
quit
EOF
updrowcount=`grep "rows affected" db_rest |cut -c2- | cut -f1 -d ' '`
done
exit
If your subject is unique, you could try something like this:
set rowcount 50000
declare #subject varchar(...)
select #subject = max( subject ) from tempdb..extract
insert into tempdb..extract ( subject )
select subject
from tablename
where fldr_id=8
and (subject > #subject OR #subject is null)
order by subject
Otherwise, use a unique column, e.g.
set rowcount 50000
declare #maxId int
select #maxId = max( id ) from tempdb..extract
insert into tempdb..extract (id, subject )
select id, subject into tempdb..extract
from tablename
where fldr_id=8
and (id > #maxId OR #maxId is null)
order by id
(Obviously, you'll want to use an indexed column.)

How can I update data entries in multiple rows using triggers in phpmyadmin

I have 3 tables -
input
value(INT)
ID(INT)
source
S_ID(INT)
S_Qty(INT)
destination
D_ID(INT)
D_Qty(INT)
Now I want to create a AFTER INSERT Trigger on input table.
For example if I insert 100 in value & 2 in ID from table input
then a trigger should be fired that increments 100 in S_Qty where S_ID=ID (i.e.2) from table source
and simultaneously decrements 100 in D_Qty where D_ID=ID (i.e.2) from table destination
PS - Assume I have stored some values in both source and destination tables
I have used the following query -
DELIMITER //
CREATE TRIGGER update_input
AFTER INSERT ON input
FOR EACH ROW
BEGIN
DECLARE I,V,D,S INT;
SELECT value INTO V FROM input;
SELECT ID INTO I FROM input;
SELECT D_Qty INTO D FROM destination WHERE D_ID = I;
UPDATE destination
SET D_Qty = D + V WHERE D_ID = I;
SELECT S_Qty INTO S FROM source WHERE S_ID = I;
UPDATE source
SET S_Qty = S - V WHERE S_ID = I;
DELETE FROM input;
END; //
DELIMITER ;

PL/SQL: How to delete records in a specific manner, for example if records of specific type X exist, delete all but one record

I'm trying to create a PL/SQL procedure where by I delete records that are grouped and selected by cursor but I only want one record remaining. I want to delete first by Xcomment, if there are multiple entries with id_number, activity_code, start_dt, activity_participation_code exist, then delete all but ONE entry with blank/null xcomment. If there are multiple entries with blank xcomment, then delete all but one with blank table_nmb. If multiple entries with blank table_nmb then delete highest sequence until only one is left. Essentially, I only want one record per all these fields. I'm having trouble thinking of how to do this so any help would be appreciated.
Here is my code so far:
Create Or Replace Function Y_Cleanup_Cursor
Return Sys_Refcursor
As
My_Cursor Sys_Refcursor;
Begin
Open My_Cursor For
Select Q.Id_Number, Q.Activity_Code, Q.Start_Dt, Q.Activity_Participation_Code, Q.Rec_Count, A.Xcomment, A.Table_Nmb, A.Xsequence
From (Select Id_Number, Activity_Code, Start_Dt, Activity_Participation_Code, Count(0) As Rec_Count
From Activity A
Group By Id_Number, Activity_Code, Start_Dt, Activity_Participation_Code
Having Count(0) > 1) Q,
Activity A
Where
Q.Id_Number = A.Id_Number And
Q.Activity_Code = A.Activity_Code And
Q.Start_Dt = A.Start_Dt And
Q.Activity_Participation_Code = A.Activity_Participation_Code;
Return My_Cursor;
End Y_Cleanup_Cursor;
Create Or Replace Procedure Help_Me_Please(Code In Varchar2)
Is
-- Declare Variables
-- I Stands For Internal Variable
L_Cursor Sys_Refcursor;
I_Id_Number Varchar2(10 Byte);
I_Xsequence Number (6);
I_Activity_Code Varchar2(05 Byte);
I_Start_Dt Varchar2(08 Byte);
I_Activity_Participation_Code Varchar2(02 Byte);
I_Table_Nmb Varchar2(15 Byte);
I_Xcomment Varchar2(255 Byte);
I_Rec_Count Number (6);
L_Counter Integer;
Begin
L_Cursor := Y_Cleanup_Cursor;
Loop
Fetch L_Cursor Into
I_Id_Number, I_Activity_Code, I_Start_Dt, I_Activity_Participation_Code, I_Rec_Count, I_Xcomment, I_Table_Nmb, I_Xsequence;
Select Count (Id_Number)
Into L_Counter
From Activity Where
Id_Number = I_Id_Number
And Activity_Code = I_Activity_Code
And Start_Dt = I_Start_Dt
And Activity_Participation_Code = I_Activity_Participation_Code
And Trim(Xcomment) Is Null;
If L_Counter <> I_Rec_Count Then
Begin
Delete From Activity
Where
Id_Number = I_Id_Number
And Activity_Code = I_Activity_Code
And Start_Dt = I_Start_Dt
And Activity_Participation_Code = I_Activity_Participation_Code
And Trim(Xcomment) Is Null;
end;
End If;
Exit When L_Cursor%Notfound;
End Loop;
Close L_Cursor;
End Help_Me_Please;
From what I gather you want to delete all rows except 1 where there are repeating columns
first make sure to backup your table:
create table [backup_table] as select * from [table];
Try This:
DELETE FROM backup_table
WHERE rowid not in
(SELECT MIN(rowid)
FROM backup_table
GROUP BY [col1], [col2]);
Col1 and col2, etc are the columns that should be identical

Resources