ORA-01031: insufficient privileges when bulk loading data from one schema to another via SQL*Loader - sql

I am trying to INSERT data into another schema's table via SQL Loader. Here is the control file:
LOAD DATA
INFILE *
INTO TABLE globalref01.dw_stg_holiday_extract
FIELDS TERMINATED BY "|"
TRAILING NULLCOLS
( ric_trd_exch,
cntry_cde,
holiday_date "TO_DATE (:holiday_date, 'YYYYMMDD')",
holiday_desc,
trd,
stl
)
Notice I'm inserting into table SCHEMA.TABLE_NAME. Since I'll be sqlldr'ing from the schema depotapp01, I'll run the following command on globalref01:
GRANT INSERT ON dw_stg_holiday_extract TO depotapp01;
Check and see if it works:
SELECT * FROM user_tab_privs_recd WHERE table_name = 'DW_STG_HOLIDAY_EXTRACT' AND owner = 'GLOBALREF01';
That confirms I have INSERT privs from depotapp01:
GLOBALREF01 DW_STG_HOLIDAY_EXTRACT GLOBALREF01 INSERT NO NO
Now, when I try to execute the sqlldr command, I get ORA-01031: insufficient privileges:
SQL*Loader: Release 10.2.0.4.0 - Production on Mon Feb 3 09:41:43 2014
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Control File: /db/platform/eq/sparc_SunOS_5.6/depot/2.0/DWRef/cfg/uat/2.1/base_config/holiday_calendar.ctl
Data File: /export/data/depotdw/DWRef/data/oats/holiday_calendar.dat
Bad File: /export/data/depotdw/DWRef/data/oats/holiday_calendar.err
Discard File: /export/data/depotdw/DWRef/data/oats/holiday_calendar.dsc
(Allow all discards)
Number to load: ALL
Number to skip: 0
Errors allowed: 200000
Bind array: 64 rows, maximum of 1000000 bytes
Continuation: none specified
Path used: Conventional
Table GLOBALREF01.DW_STG_HOLIDAY_EXTRACT, loaded from every logical record.
Insert option in effect for this table: INSERT
TRAILING NULLCOLS option in effect
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
RIC_TRD_EXCH FIRST * | CHARACTER
CNTRY_CDE NEXT * | CHARACTER
HOLIDAY_DATE NEXT * | CHARACTER
SQL string for column : "TO_DATE (:holiday_date, 'YYYYMMDD')"
HOLIDAY_DESC NEXT * | CHARACTER
TRD NEXT * | CHARACTER
STL NEXT * | CHARACTER
SQL*Loader-929: Error parsing insert statement for table GLOBALREF01.DW_STG_HOLIDAY_EXTRACT.
ORA-01031: insufficient privileges
So my question is, now that I know I have INSERT privileges, what other privileges do I need to grant in order for this to work?

I think you also need the SELECT privilege in most cases because SQL*Loader performs checks before inserting.
In particular, the default loading option is INSERT:
INSERT
This is SQL*Loader's default method. It requires the table to
be empty before loading. SQL*Loader terminates with an error if the
table contains rows.
In order to check that the table is empty, the account used by SQL*Loader needs the SELECT privilege. You might not need it if loading as APPEND instead. Conversely, if you use the REPLACE or TRUNCATE option, you'll need additional privileges.

Related

Updating first 7 characters of string with another 3 characters using SQL, throws "Error 19 - UNIQUE constraint failed: MGOFile.File."

I have a rather simple DB with a column called File, and I need to remove the first 7 characters of each row, and replace with a new string. I thought I had the code sorted, but I am getting error "SQLite3 Error 19 - UNIQUE constraint failed: MGOFile.File."
My table name is MGOFile, and the column is File. This is a simple select statement on the first few rows, the left column is the raw data, the right is what I need the resultant rows to look like...
I query my table using this:
'''sql
SELECT
File,
'T:\'|| substr(File, 8,2000) as File
FROM
MGOFile
WHERE
file like 'M:\_TV%';
'''
I then tried updating using this:
UPDATE MGOFile
SET File = 'T:\' || substr(File, 8, 2000)
WHERE File like 'M:\_TV%';
But here is where my error comes in, this fails with an error:
I am sure I am doing something simple wrong, but I have done plenty of Googling but all responses are over my head, this is the most advanced SQL I have tried to do!
Any ideas on how to can update these strings with some simple SQLite?
As checking for duplicates doesn't appear to detect the issues. Perhaps getting values at the time of the issue may assist. Do you have Triggers by any-chance? These will sometimes propagate an error which will be reported as being with the table that triggered the trigger.
As such perhaps consider adding a table to log such data along with a BEFORE UPDATE TRIGGER to actually log the information at run time. To stop the data being rolled back and thus undoing the logged information OR FAIL needs to be used.
Important as the updates will not be rolled back updates will have been applied. It is suggested that the above is used on a test database.
-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
BEFORE UPDATE ON MGOFile
BEGIN
UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
END
;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
SET File = 'T:\' || substr(File, 8, 2000)
WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail but should be run after the fail
This would, assuming the fail, record
the nth update in the counter column
the value in the File column before the change in the lastfile_before column.
the value that the File column would be updated to in the **lastfile_after* columns.
the last rowid (failing) of the row in the MGOFile table (this does assume that the MGOFile table is not a table defined using WITHOUT ROWID).
If the table was defined with the WITHOUT ROWID then you could change , id_of_the_row = 0;. The value will then be meaningless.
Testing/Results the version of the above that was used to test the above is :-
-- Solely for testing the code below
DROP TABLE IF EXISTS MGOFile;
CREATE TABLE IF NOT EXISTS MGOFile (File TEXT PRIMARY KEY);
-- Some testing data
INSERT INTO MGOFile VALUES
('M:\_TV/9-1-1.so2e09.web.x264-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x265-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x277-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x279-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x280-tbs[eztv].mkv')
;
SELECT substr(File,170,8) FROM MGOFile GROUP BY Substr(File,8,170) HAVING count() > 1;
-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
BEFORE UPDATE ON MGOFile
BEGIN
UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
END
;
SELECT * FROM MGOFile;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail
When the above is run then the message is :-
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
WHERE File like 'M:\_TV%'
> UNIQUE constraint failed: MGOFile.File
> Time: 0.094s
Running SELECT * FROM lastupdated; returns :-
counter
6
lastfile_before =
M:_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv
lastfile_after
T:\9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x27
id_of_the_row
6
In the above contrived example the issue can easily be determined (albeit that the duplicate search also found the same issue) as the error is on the 6th row and at the row that contains mkv.so2e09.web.x278-tbs[eztv] but was truncated by the update to .mkv.so2e09.web.x27 hence it is a duplicate of the 5th row which has .mkv.so2e09.web.x277-tbs[eztv] but was also truncated to .mkv.so2e09.web.x27.
P.S. Have you tried using just
UPDATE MGOFile
SET File = 'T:\' || substr(File, 8)
WHERE File like 'M:\_TV%';
i.e. removing the truncation.
The error seems quite clear to me. You are changing the file name to a name that is already in the table.
You can identify the duplicates by running:
SELECT f.*
FROM MGOFile f
WHERE EXISTS (SELECT 1
FROM MGOFile f2
WHERE f2.File = 'T:\'|| substr(File, 8,2000)
) AND
f.file LIKE 'M:\_TV%';
I don't know what you want to do about the duplicate.

Storing oracle error/query result in a table

Does anyone know if this is possible?
Example:
CREATE TABLE XPTO (
this_is_an_error_because_there_is_no_data_type
);
Query Result:
"**Error starting at line X in command:
blablabla
SQL ERROR: ORA-02263**"
Is it possible to save the query result in a table?
I'm making an "installation" script with CREATE tables/procedures, GRANT's simple stuff, but I want to know if it's possible to save in a table the errors that may popup during the installation of my tables or whatever it is in there (in my install file .sql).
Any help, ideas, work around/s, would be appreciated. Thanks guys!
In SQL*Plus this can be done with SQL*Plus error logging.
Enable error logging:
SQL> set errorlogging on
Run the script:
SQL> CREATE TABLE XPTO (
2 this_is_an_error_because_there_is_no_data_type
3 );
this_is_an_error_because_there_is_no_data_type
*
ERROR at line 2:
ORA-00972: identifier is too long
At the end, all errors are stored in the table SPERRORLOG.
SQL> select * from sperrorlog;
USERNAME
------------------------------------------------
TIMESTAMP
------------------------------------------------
SCRIPT
------------------------------------------------
IDENTIFIER
------------------------------------------------
MESSAGE
------------------------------------------------
STATEMENT
------------------------------------------------
JHELLER
25-JAN-16 01.43.13.000000 PM
ORA-00972: identifier is too long
CREATE TABLE XPTO (
this_is_an_error_because_there_is_no_data_type
)
As Tony Andrews said in the comment, SPOOL is the most common method for doing this. But that's because very few SQL*Plus scripts are fully automated. If you are aiming for true automation you'll need something like SQL*Plus error logging or whenever sqlerror exit failure to detect errors.

Importing a pgsql file via pgadmin

I work on MySQL, but one of my client gave me a project that uses postgreSql. He gives me the project files and db file with extension '.pgsql'.
I installed pgadmin and created a test db, but don't know how to import pgsql file. I tries copy-paste of queries in script editor, till tables everything is executing fine, but at the time of data queries, its throwing error.
And data format is also strange, don't know whether its the correct query format or not.
This is the glimpse of pgsql file:
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: kjh; Type: TABLE; Schema: public; Owner: design; Tablespace:
--
CREATE TABLE kjh (
mknh integer NOT NULL,
jkh integer NOT NULL
);
ALTER TABLE public.kjh OWNER TO design;
--
-- Name: TABLE kjh; Type: COMMENT; Schema: public; Owner: design
--
//..And so on
These lines in pgsql files are throwing error:
--
-- Data for Name: kjh; Type: TABLE DATA; Schema: public; Owner: design
--
COPY kjh (mknh, jkh) FROM stdin;
1 1
\.
--
-- Data for Name: w_ads; Type: TABLE DATA; Schema: public; Owner: design
--
COPY w_ads (id, link, city, type, name, enabled, "time", hits, isimg) FROM stdin;
44 # -1 0 1 t 1 20 1
\.
Any suggestions?
You are likely running into problems with delimiters, try something like this:
COPY kjh (mknh, jkh) FROM stdin WITH DELIMITER ' ';
1 1
\.
This should execute just fine.
Also, note, that your pgsql file have inconsistent spaces count between values, so you may have to prepare this file replacing multiple spaces in values with single delimiter (two spaces with single space delimiter will result in error, since postgres will assume you providing empty column value).
And I would suggest you to choose another delimiter instead of space, something like ; or ^.
Not sure if COPY ... FROM stdin will work from pgadmin (well, it should), but if it fails, try to run this query from CLI using psql command.
For more info on delimiters and copy syntax, refer to docs.

Insert rows from a table in another database

How can rows be inserted into a table from a table in a remote database?
We currently have a stored procedure which does this using a database link. However, we are having to delete the link because our company policy doesn't allow their usage.
begin
...
execute immediate 'insert into '|| table_name
|| ' (select * from schema_name.'|| table_name ||'#link)';
...
end;
I'm unable to use the COPY command as it appears to be not recognized.
COPY FROM username/pwd#SID
insert into table_name using (select *
from table_name);
Error report:
SQL Error: ORA-00926: missing VALUES keyword
00926. 00000 - "missing VALUES keyword"
*Cause:
*Action:
According to this SQL Plus page, COPY command is now obsolete.
Your Query syntax is slightly wrong, and you just need to specify INSERT/REPLACE/CREATE .. and INTO is NOT needed.
COPY is not obsolete, but it ends up with some encoding issues.
You would use the line continuation character to get around that.
COPY
FROM username/pwd#SID
TO username/pass#SID2
insert
table_name
using
select * from schema_name.table_name;
You can also, download the table data into a text file, and use SQL*Loader to load the data into the another Database.
I prefer the SQL*Loader option! Since maintenance is easy!
For download,
- you can either use SPOOL with delimiter option as mentioned Here
- Write a ProC/PLSQL to output the data into a File (Method 4 in ProC, OR select column names from dba_columns))

The object name 'FacetsXrefStaging.Facets.Facets.FacetsXrefImport' contains more than the maximum number of prefixes. The maximum is 2

Hi i have created a proc which truncates and reseeds the no of records from the tables. but i am getting the error : The object name 'FacetsXrefStaging.Facets.Facets.FacetsXrefImport' contains more than the maximum number of prefixes. The maximum is 2.
Create proc TruncateAndReseedFacetsXrefStagingTables
'
'
Declare variables
'
'
SET #iSeed = ( SELECT CASE WHEN MAX(FacetsXrefId) IS NULL
THEN -2147483648
ELSE MAX(FacetsXrefId) + 1
END
FROM FacetsXref.Facets.Facets.FacetsXrefCertified
)
TRUNCATE TABLE FacetsXrefStaging.Facets.Facets.FacetsXrefImport
DBCC CHECKIDENT ('FacetsXrefStaging.Facets.FacetsXrefImport', RESEED,#iSeed )
TRUNCATE TABLE FacetsXrefStaging.Facets.FacetsXrefImport
Can anybody help me with that.
I AM USING SQL SERVER 2005.
I am actually having this problem that the OP had - and there's no typo involved in my situation. :-)
This is a table that exists on a different server from the server I'm on. The servers are linked.
The queries above and below the TRUNCATE statement work just fine.
The TRUNCATE does not work.
...Anonymized to protect the innocent...
select count(*) as mc from servername.databasename.dbo.tablename -- works
truncate TABLE [servername].[databasename].[dbo].[tablename] -- error
select count(*) as mc from servername.databasename.dbo.tablename -- works
Error message:
The object name 'servername.databasename.dbo.'
contains more than the maximum number of prefixes. The maximum is 2.
Yes - the TRUNCATE is commented but I noticed that after I did all the blur effects and wasn't going to go back and re-make the image - sorry :-( - ignore the begin/end tran and the comment markers - the TRUNCATE does not work - see error above.