Is it possible to simply change character in name of tables columns? At the moment columns have seperator - and I want to change it with underscore (_) . Is it possible to do it easy with 1 click or should I go through all tables and change it by hand?
I don't know oracle SQL data modeler. If you have access to SQL*Plus or another developer tool, you can run script, it will change all columns of tables in your schema:
begin
for i in (select table_name, column_name from user_tab_columns) loop
if instr(i.column_name, 'A') > 0 then
execute immediate 'alter table ' || i.table_name || ' rename column ' ||
i.column_name || ' to ' || replace(i.column, 'A', 'B');
end if;
end loop;
end;
/
Here 'A' is symbol that you want to replace and 'B' - new symbol to use. But be careful, such scripts can be dangerous. Try it on test schema first.
Related
I need a query for db2 and oracle which can be used for exporting data into CSV files and for datatype like BLOB, CLOB it will have an empty string.
eg:
Table-->
col1(char),col2 (blob),clo3 (date)
video_1,blob, '1998-05-02'
csv file --->
col1,col2,col3
"video_1","",'1998-05-02'
You may generate the corresponding statements dynamically to execute them later in Db2.
Below is an example for 2 system tables SYSIBM.SYSTABLES and SYSIBM.SYSTABLESPACES.
You may run it as is to get 2 EXPORT commands with the corresponding SELECT statements.
The output can be used as is to execute it as a script of commands with the Db2 Command Line Processor (db2 -tf out_file.sql in a session with a database connection established). If you comment out the string with EXPORT, you may get pure corresponding SELECT statements to use them with some another tool capable to save the result of an arbitrary SELECT statement to a CSV file (as the Db2 EXPORT command does it).
SELECT
'EXPORT TO ' || RTRIM (T.TABSCHEMA) || '.' || T.TABNAME || '.csv OF DEL'
||' SELECT ' || LISTAGG (CASE WHEN C.TYPENAME LIKE '%LOB' THEN '''''' ELSE '"' || C.COLNAME || '"' END, ', ') WITHIN GROUP (ORDER BY C.COLNO)
||' FROM "' || T.TABSCHEMA || '"."' || T.TABNAME || '";'
FROM SYSCAT.TABLES T
JOIN SYSCAT.COLUMNS C ON C.TABSCHEMA = T.TABSCHEMA AND C.TABNAME = T.TABNAME
WHERE T.TABSCHEMA = 'SYSIBM' AND T.TABNAME IN ('SYSTABLES', 'SYSTABLESPACES')
GROUP BY T.TABSCHEMA, T.TABNAME
I get the following error message in a stored procedure that I created:
ORA-00933: SQL command not properly ended
ORA-06512: at line 11
I have tried Googling it, but could not find anything applicable as it tells my to try to eliminate any 'ORDER BY'.
declare
cursor a_tab is
select table_name
from all_tables
where owner = 'OFFERINGWORKSPACE'
and (TABLE_NAME like 'EBA_%' or TABLE_NAME = 'SURVEY_2.0');
v_tab_name varchar2(500);
begin
open a_tab;
loop
fetch a_tab into v_tab_name;
exit when a_tab%notfound;
EXECUTE IMMEDIATE 'delete ' || v_tab_name;
end Loop;
close a_tab;
open a_tab;
Loop
fetch a_tab into v_tab_name;
Exit when a_tab%notfound;
EXECUTE IMMEDIATE 'insert into ' || v_tab_name || '(select * from OFFERINGWORKSPACE.'||v_tab_name ||')';
End Loop;
Close a_tab;
End;
There is a clue in your cursor query:
... TABLE_NAME = 'SURVEY_2.0');
The period in that breaks the database object naming rules:
Nonquoted identifiers can only contain alphanumeric characters from your database character set and the underscore (_). Database links can contain periods (.) and "at" signs (#).
so that table name must be a quoted identifier. You therefore need to quote it in your statements:
EXECUTE IMMEDIATE 'delete "' || v_tab_name || '"';
and
EXECUTE IMMEDIATE 'insert into "' || v_tab_name
|| '"(select * from OFFERINGWORKSPACE."'||v_tab_name ||"')';
db<>fiddle showing the errors from those commands (simplified to one schema, and static SQL), and how adding the double quotes fixes them.
I need to change the SRID (set it to NULL) in the geometry objects of all tables in a specific schema (for a specific user)
The command:
UPDATE my_table t SET t.geometrie.sdo_srid = null;
works fine for a single table.
When I try to do it in a loop for all tables of a specific owner:
BEGIN
FOR my_tables IN (
SELECT TABLE_NAME from all_tables where OWNER = 'LANDWERTZONEN' AND TABLE_NAME NOT LIKE 'GOOM%' AND TABLE_NAME NOT LIKE '%BKP'
)
LOOP
DBMS_OUTPUT.PUT_LINE('UPDATE ' || my_tables || ' t SET t.geometrie.sdo_srid = null');
END LOOP;
END;
I get the error:
pls-00306 wrong number or types of arguments in call to '||'
What could be the problem here?
Wrong concatenation? Wrong call?
Any suggestions are very welcome.
Besides the syntax error that Littlefoot pointed out, you may extend the logic to actually perform the update rather than printing out the UPDATE statement:
DECLARE
sql_stmt varchar2(256);
BEGIN
FOR st IN (
SELECT OWNER, TABLE_NAME, COLUMN_NAME
FROM all_tab_columns
WHERE OWNER = 'LANDWERTZONEN'
AND TABLE_NAME NOT LIKE 'GOOM%'
AND TABLE_NAME NOT LIKE '%BKP'
AND DATA_TYPE = 'SDO_GEOMETRY'
)
LOOP
sql_stmt := 'UPDATE ' || st.owner ||'.' || st.table_name || ' t SET t.'|| st.column_name ||'.sdo_srid = null';
DBMS_OUTPUT.PUT_LINE('Executing ' || sql_stmt);
execute immediate sql_stmt;
COMMIT;
END LOOP;
END;
/
This actually restricts the change to actual spatial tables / columns.
Note that you must make sure the spatial indexes are dropped before execution (and update metadata and recreate the spatial indexes after execution).
BUT I would question the reason for setting the SRIDs to NULL. This will seriously remove functionality: you will no longer be able to perform any measurements (area, length, distances). Also you will no longer be able to relate the data with data that has explicit SRIDs (like a GPS point). And if the data is actually geodetic (long/lat) then operations like within_distance, buffer generation ... are essentially no longer possible.
Our advice is to always explicitly use the correct SRIDs.
How about this:
DBMS_OUTPUT.PUT_LINE('UPDATE ' || my_tables.table_name || ' t SET t.geometrie.sdo_srid = null');
-----------
You forgot to add table name from a cursor.
I am getting the following error:
00000 - "missing right parenthesis"
when I execute my procedure:
CREATE OR REPLACE PROCEDURE ALTER_TABLE_COLUMN_NOT_NULL(
var_tabname IN VARCHAR2,
var_clname IN VARCHAR2,
var_defvalue IN VARCHAR2 )
IS
l_isnull VARCHAR2(1);
BEGIN
SELECT isnull INTO l_isnull FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = var_tabname AND COLUMN_NAME = var_clname;
IF l_isnull = 'Y' THEN
EXECUTE IMMEDIATE 'ALTER TABLE ' || var_tabname ||
' MODIFY COLUMN (' || var_clname ||
' DEFAULT ' || var_defvalue || ' NOT NULL)';
END IF;
END;
I know that according to the error, the right parenthesis is missing. I tried many ways of rewriting it, but I can't manage to fix it.
I am executing my procedure the following way:
BEGIN
ALTER_TABLE_COLUMN_NOT_NULL('FIRSTNAME', 'PRICE', '-');
END;
Writing dynamic SQL is hard, because compilation errors become runtime errors.
In this case I think the problem is that MODIFY COLUMN is wrong syntax. It's just MODIFY.
You may also run into some problems with your default of '-'. If price is a number that will fail because - is an invalid number. If price is a string you'll need to escape the passed value with additional quotes.
But probably you want to make this generic, so you need to write some more sophisticated handling which tests for datatype of the target column and formats default value appropriately.
"Can u give me a hint or any link how one can determine the datatype of a passed value in plsql?"
It's not the passed value which matters, it's the datatype of the modified column. You can get that from the USER_TAB_COLUMNS view which you're already querying.
Print your query to make sure it written correctly
DBMS_OUTPUT.PUT_LINE('ALTER TABLE ' || var_tabname || ' MODIFY COLUMN (' || var_clname || ' DEFAULT ' || var_defvalue || ' NOT NULL)');
I am doing something like this in a procedure to clear all data from all tables in my database.
LOOP
dbms_utility.exec_ddl_statement('alter table ' || c.owner || '.' || c.table_name || ' disable constraint ' || c.constraint_name);
END LOOP;
.
.
.
LOOP
EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || t.table_name ;
END LOOP;
Now , this throws the following error :
ORA-03291: Invalid truncate option - missing STORAGE keyword
ORA-06512: at "MYSCHEMA.CLEAR_DATA", line 15
ORA-06512: at line 2
Process exited.
Disconnecting from the database MYDB.
Why is a storage keyword mandatory? I thought DROP STORAGE was the default.
Even specifying storage close, as in,
EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || t.table_name || 'DROP STORAGE';
doesn't help. The error is the same.
I thought it might have something to do with foreign constraints on some tables. Hence, the 'disable constraint' earlier in the script
I would suggest that you build the command you are executing in a string variable, output it using dbms_output, then execute it. This way you will see exactly what it is trying to execute that is generating the error.
One thing that could be causing this error is if you have a table name with a space in it (yes, it's possible). The solution if that is the case is to wrap the table name in double quotes.
dev> create table "dave exp" (x number);
Table created.
dev> truncate table dave exp;
truncate table dave exp
*
ERROR at line 1:
ORA-03291: Invalid truncate option - missing STORAGE keyword
dev> truncate table "dave exp";
Table truncated.
Change your program:
put your truncate command in a PL/SQL variable prior to execution
add an exception handler that outputs the truncate statements via dbms_output or utl_file (fflush after each one) when you encounter an exception:
LOOP
BEGIN
...
v_sql := 'TRUNCATE TABLE ' || t.table_name ;
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
dbms_output.put_line(v_sql);
END;
END LOOP;
This should show you the statement causing the issue.
truncate table Table_NAME drop storage;