ORA-00911: invalid character error while truncating table - database

I have a table that name is _VERSION_HISTORY I got ORA-00911 error while truncating this table. Oracle allow the name start with underscore(_) but throws an error while truncating it. Is it a silly mistake?

Oracle does not allow database object names to start with an underscore:
SQL> create table _T34 (col1 number);
create table _T34 (col1 number)
*
ERROR at line 1:
ORA-00911: invalid character
SQL>
So you must have used double quotes when creating that table:
SQL> create table "_T34" (col1 number);
Table created.
SQL>
Having done that once you must use double quotes whenever you reference that object?
SQL> truncate table "_T34";
Table truncated.
SQL>
So is it "a silly mistake"? Yes, but alas on your part (or whoever decided on using double-quotes to circumvent Oracle's naming conventions). Find out more.

It seems like you have tried to execute SQL statement with a special charter in it. I don't think it is to do with the truncate command. You might just replace the truncate with a simple Select and test this scenario. Note that the special character might appear as white space due to the font you are using.

Related

Sybase ASE issue dropping unique constraint

When dropping a unique constraint both using Sybase Central or iSQL, the drop statement shown is as follows;
alter table user_database.dbo.table_name drop constraint contraint_name
But execution fails with different errors, like this:
If constraint name is between single quotes, the command returns:
Incorrect syntax near the word 'constraint'
If constraint name is between square braquets, the command returns:
The identifier that starts with '[constraint_name' is too long. Maximum lenght is 28.
If constraint name is written alone, the command returns
Incorrect syntax near '.'
I'm 'sa' user and I've tried issuing commands from both master and user_database. Any suggestions?
Don't use any quotes or brackets, and pls post the full final statement. Also try leaving off the db name (make sure you are in that database).

Problematic nameless table in Postgresql

I actually don't know how I've done it : but I got a nameless table into my postgres DB. Needless to say that such a table is problematic, it doesn't get erased, neither could you change it in any way.
Here is a picture of how it looks on the pgAdmin explorer :
As for its declaration, it goes like this :
CREATE TABLE
(
_id_ integer NOT NULL DEFAULT nextval('bu_b__id__seq'::regclass),
pt_utilisateur integer,
pt_date date,
lon double precision,
lat double precision,
CONSTRAINT PRIMARY KEY (_id_)
)
So, one simple question : how can I delete this table (since trying to delete it comes to using its name... which doesn't exist !) ?
Regards.
If this is NOT about a table which name is not displayable due to encoding / font issues you can do this:
Determine the table OID from the system catalogues.
Set a new table name in the system catalogues to a temporary name. Use the OID as an identifer
Re-rename the table to something useful (or just drop it).
This of course assumes, that you have superuser access to the database.
The first step - determine the OID from the catalogue:
SELECT oid, relname FROM pg_class WHERE length(relname) <= 1;
If you don't get any result the table has a name - it is just not displayable. In this case just skip the WHERE part and look with your eyes.
The second step - change the system catalogue:
UPDATE pg_class SET relname = 'foo' WHERE oid = /*OID from step 1*/;
In any case - don't stop here, you must proceed.
The third step - cleanup
PostgreSQL stores the table name in more than one place (e.g. pg_type). Some tools might depend on this. To clean this up you must either drop the table (and hence the unrenamed stuff) OR you must rename the table again using the official tools.
ALTER TABLE foo RENAME TO /*somthing real*/;
or
DROP TABLE foo;
The usual warnings: You are munching in the internals of PostgreSQL - don't do silly things and do it on your own risk :-)
I don't use Postgresql but I guess you can delete that table by following steps:
Take the sql dump
Delete the database
Remove that nameless table from the dump and restore sql dump

Openedge progress - Can't escape single quote - Is this a bug?

I am trying to run a simple query over jdbc ALTER TABLE Customer ALTER \"Cust-Name\" set PRO_DESCRIPTION 'Customer Name'
This works perfectly well. But, when I have to set description as "Customer's Name", i.e, include a single quote - I am unable to get it to work.
I tried
ALTER TABLE Customer ALTER \"Cust-Name\" set PRO_DESCRIPTION 'Customer~'s Name'
ALTER TABLE Customer ALTER \"Cust-Name\" set PRO_DESCRIPTION 'Customer~~'s Name'
ALTER TABLE Customer ALTER \"Cust-Name\" set PRO_DESCRIPTION 'Customer\\'sName'
ALTER TABLE Customer ALTER \"Cust-Name\" set PRO_DESCRIPTION "Customer's Name"
Nothing works.
I don't know Progress, but the SQL standard is to duplicate the single quote:
'Customer''s Name'
While I was learning Progress I encountered a function called QUOTER that can be used in your situation.
QUOTER function
Converts the specified data type to CHARACTER and encloses the results
in quotes when necessary.
The QUOTER function is intended for use in QUERY-PREPARE where a
character predicate must be created from a concatenated list of string
variables to form a WHERE clause. In order to process variables,
screen values, and input values so that they are suitable for a query
WHERE clause, it is often necessary to enclose them in quotes. For
example, European-format decimals and character variables must always
be enclosed in quotes. You can use the Quoter function to meet that
requirement.

SQL Server insert or query between servers ingnores column in table starting with a number?

I am trying to query between two servers which have identical tables (used the same create statement for both). When I try to insert the results from Server A to Server B I get an error indicating "Column name or number of supplied values does not match table definition."
Query run on server A
Insert into ServerB.Database1.dbo.Table1
Select *
from Table1
The error is clear, but what isn't clear is the reason that it is generated. The definitions of the two tables are identical. What I was finally able to isolate was a table name that starts with a numeric value is not being recognized.
When I run this on ServerA:
Select *
from ServerB.Database1.dbo.Table1
The field with the numeric value is not shown in the results set of they query. The short term fix was to rename the field in the database, but why is this happening?
I am curious about the collation too, but really the answer is to wrap the object names in square brackets. i.e. SELECT [1col], [2col], [etc] FROM [1database].[2owner].[3table]. This way SQL with recognize each as an object name and not a function.
One other thing to keep in mind is to not use splat (*) in your select statement, this has potential problem of it's own. For example, you could run into an error in your Insert if the ServerA's table1 structure was change and ServerB's table one stayed the same.

Oracle considers empty strings to be NULL while SQL Server does not - how is this best handled?

I have to write a component that re-creates SQL Server tables (structure and data) in an Oracle database. This component also has to take new data entered into the Oracle database and copy it back into SQL Server.
Translating the data types from SQL Server to Oracle is not a problem. However, a critical difference between Oracle and SQL Server is causing a major headache. SQL Server considers a blank string ("") to be different from a NULL value, so a char column can be defined as NOT NULL and yet still include blank strings in the data.
Oracle considers a blank string to be the same as a NULL value, so if a char column is defined as NOT NULL, you cannot insert a blank string. This is causing my component to break whenever a NOT NULL char column contains a blank string in the original SQL Server data.
So far my solution has been to not use NOT NULL in any of my mirror Oracle table definitions, but I need a more robust solution. This has to be a code solution, so the answer can't be "use so-and-so's SQL2Oracle product".
How would you solve this problem?
Edit: here is the only solution I've come up with so far, and it may help to illustrate the problem. Because Oracle doesn't allow "" in a NOT NULL column, my component could intercept any such value coming from SQL Server and replace it with "#" (just for example).
When I add a new record to my Oracle table, my code has to write "#" if I really want to insert a "", and when my code copies the new row back to SQL Server, it has to intercept the "#" and instead write "".
I'm hoping there's a more elegant way.
Edit 2: Is it possible that there's a simpler solution, like some setting in Oracle that gets it to treat blank strings the same as all the other major database? And would this setting also be available in Oracle Lite?
I don't see an easy solution for this.
Maybe you can store your values as one or more blanks -> ' ', which aren't NULLS in Oracle, or keep track of this special case through extra fields/tables, and an adapter layer.
My typical solution would be to add a constraint in SQL Server forcing all string values in the affected columns to have a length greater than 0:
CREATE TABLE Example (StringColumn VARCHAR(10) NOT NULL)
ALTER TABLE Example
ADD CONSTRAINT CK_Example_StringColumn CHECK (LEN(StringColumn) > 0)
However, as you have stated, you have no control over the SQL Database. As such you really have four choices (as I see it):
Treat empty string values as invalid, skip those records, alert an operator and log the records in some manner that makes it easy to manually correct / re-enter.
Convert empty string values to spaces.
Convert empty string values to a code (i.e. "LEGACY" or "EMPTY").
Rollback transfers that encounter empty string values in these columns, then put pressure on the SQL Server database owner to correct their data.
Number four would be my preference, but isn't always possible. The action you take will really depend on what the oracle users need. Ultimately, if nothing can be done about the SQL database, I would explain the issue to the oracle business system owners, explain the options and consequences and make them make the decision :)
NOTE: I believe in this case SQL Server actually exhibits the "correct" behaviour.
Do you have to permit empty strings in the SQL Server system? If you can add a constraint to the SQL Server system that disallows empty strings, that is probably the easiest solution.
Its nasty and could have unexpected side effects.. but you could just insert "chr(0)" rather than ''.
drop table x
drop table x succeeded.
create table x ( id number, my_varchar varchar2(10))
create table succeeded.
insert into x values (1, chr(0))
1 rows inserted
insert into x values (2, null)
1 rows inserted
select id,length(my_varchar) from x
ID LENGTH(MY_VARCHAR)
---------------------- ----------------------
1 1
2
2 rows selected
select * from x where my_varchar is not null
ID MY_VARCHAR
---------------------- ----------
1
NOT NULL is a database constraint used to stop putting invalid data into your database. This is not serving any purpose in your Oracle database and so I would not have it.
I think you should just continue to allow NULLS in any Oracle column that mirrors a SqlServer column that is known to contain empty strings.
If there is a logical difference in the SqlServer database between NULL and empty string, then you would need something extra to model this difference in Oracle.
I'd go with an additional column on the oracle side. Have your column allow nulls and have a second column that identifies whether the SQL-Server side should get a null-value or empty-string for the row.
For those that think a Null and an empty string should be considered the same. A null has a different meaning from an empty string. It captures the difference between 'undefined' and 'known to be blank'. As an example a record may have been automatically created, but never validated by user input, and thus receive a 'null' in the expectation that when a user validates it, it will be set to be empty. Practically we may not want to trigger logic on a null but may want to on an empty string. This is analogous to the case for a 3 state checkbox of Yes/No/Undefined.
Both SQL and Oracle have not got it entirely correct. A blank should not satisfy a 'not null' constraint, and there is a need for an empty string to be treated differently than a null is treated.
If you are migrating data you might have to substitute a space for an empty string. Not very elegant, but workable. This is a nasty "feature" of Oracle.
I've written an explanation on how Oracle handles null values on my blog a while ago. Check it here: http://www.psinke.nl/blog/hello-world/ and let me know if you have any more questions.
If you have data from a source with empty values and you must convert to an Oracle database where columns are NOT NULL, there are 2 things you can do:
remove the not null constraint from the Oracle column
Check for each individual column if it's acceptable to place a ' ' or 0 or dummy date in the column in order to be able to save your data.
Well, main point I'd consider is absence of tasks when some field can be null, the same field can be empty string and business logic requires to distinguish these values. So I'd make this logic:
check MSSQL if column has NOT NULL constraint
check MSSQL if column has CHECK(column <> '') or similar constraint
If both are true, make Oracle column NOT NULL. If any one is true, make Oracle column NULL. If none is true, raise INVALID DESIGN exception (or maybe ignore it, if it's acceptable by this application).
When sending data from MSSQL to Oracle, just do nothing special, all data would be transferred right. When retrieving data to MSSQL, any not-null data should be sent as is. For null strings you should decide whether it should be inserted as null or as empty string. To do this you should check table design again (or remember previous result) and see if it has NOT NULL constraint. If has - use empty string, if has not - use NULL. Simple and clever.
Sometimes, if you work with unknown and unpredictable application, you cannot check for existence of {not empty string} constraint because of various forms of it. If so, you can either use simplified logic (make Oracle columns always nullable) or check whether you can insert empty string into MSSQL table without error.
Although, for the most part, I agree with most of the other responses (not going to get into an argument about any I disagree with - not the place for that :) )
I do notice that OP mentioned the following:
"Oracle considers a blank string to be the same as a NULL value, so if a char column is defined as NOT NULL, you cannot insert a blank string."
Specifically calling out CHAR, and not VARCHAR2.
Hence, talking about an "empty string" of length 0 (ie '' ) is moot.
If he's declared the CHAR as, for example, CHAR(5), then just add a space to the empty string coming in, Oracle's going to pad it anyway. You'll end up with a 5 space string.
Now, if OP meant VARCHAR2, well yeah, that's a whole other beast, and yeah, the difference between empty string and NULL becomes relevant.
SQL> drop table junk;
Table dropped.
SQL>
SQL> create table junk ( c1 char(5) not null );
Table created.
SQL>
SQL> insert into junk values ( 'hi' );
1 row created.
SQL>
SQL> insert into junk values ( ' ' );
1 row created.
SQL>
SQL> insert into junk values ( '' );
insert into junk values ( '' )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
SQL>
SQL> insert into junk values ( rpad('', 5, ' ') );
insert into junk values ( rpad('', 5, ' ') )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
SQL>
SQL> declare
2 lv_in varchar2(5) := '';
3 begin
4 insert into junk values ( rpad(lv_in||' ', 5) );
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>

Resources