I looked around for an answer to this. How to add a column using SQL in an Oracle Database.
I keep finding the same answer, but my Oracle SQL Developer tool keeps telling me that the syntax is wrong even though I write it exactly as they do.
What am I missing exactly? (Before you ask, yes I do use ALTER TABLE before this)
The syntax is supposed to be:
ADD Column_Name constraint Data_Type;
Issue is, I have no constraints for this column so I've seen examples not use it. I tried that as well and I get the same error. The value can be null and have no constraints, yet I am not allowed to do this:
ADD SERIES_YEAR NUMBER(2,10);
Any suggestions? It's probably something incredibly simple.
EDIT: Here is the error it gives me:
You are missing parentheses. Try the following:
ALTER TABLE
Foo
ADD
(
SERIES_YEAR NUMBER(2,10) NOT NULL,
);
You have to write the data type before the constraint, not the opposite, like:
ADD
(
column1_name column1_datatype column1_constraint,
column2_name column2_datatype column2_constraint
);
Related
I have been trying recently to change the default value of a column as described here. The solution I found there requires deleting the default constraint, which requires knowing the name of that constraint.
The problem I am having is that I do not know how to find out the constraint name in MariaDB. In the same post, these solutions were suggested:
SELECT NAME FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('dbo.MyTable');
sp_help MyTable
sp_helpconstraint MyTable
All of these produce syntax errors in MariaDB, since they all seem to be for MSSQL or MySQL.
So, what do I need to do to find out the constraint name?
Constraints are shown in the output of SHOW CREATE TABLE <table-name> along with everything else that relates to a table.
We had another developer come through and complete some work for us. Unfortunately he didn’t work well within our team and management let him go.
Because of this now I’m stuck debugging his code and undoing work that was done. He did not document his code (one of the reasons he was let go), rarely notating anything, therefore I have no idea where to begin looking.
When I run a basic SELECT on two specific tables in our DB:
SELECT * FROM table_name
Using SQL Server Management Studio I get this...
Msg 207, Level 16, State 1, Line 1
Invalid column name 'eventTime'.
There was an eventTime column but wasn’t necessary and wasn't being used in any PHP file, however it seems somehow directly tied to the table now and I have no idea where to look to find it. The error message provided is pointing to my SELECT statement, but there is nothing wrong with it, nor does it even reference the eventTime column.
I’ve looked and there don’t seem to be any triggers or stored procedures referencing this table. Is there another way I can try to track this down?
This sounds like a hard'ish problem. Here are some ideas.
My first thought is that table_name is a view, and somehow the view has gotten out-of-sync with the underlying table definitions. I have seen problems with types in some circumstances. I imagine the same could happen with column names.
The next thought is that table_name has computed columns. In this case, the computed columns could be using a function and the function call could be generating the error. I cannot think of any other way to run code with a simple select.
I don't think the problem would be a foreign key constraint unless. So, a third option is that a foreign key constraint is referencing a table in the same database but a different schema. The different schema could have permissions that make the table inaccessible.
For any of these, scripting out the definition in SSMS will help you fix the problem.
Is there a column comment syntax that allows me to specify a column comment directly where I declare the column in the create table statement (i.e. inline)? The 11g spec does not mention anything, on another page something is mentioned but I could not get it to work. There is a way to specify comments after creating the table, but I think it is annoying that the comment is separated from the field definition. I am looking for something like this (which does not work):
create table whatever (
field number(15,0) primary key comment 'primary key generated from sequence pkseq',
...
)
I'm afraid the "annoying" COMMENT ON syntax is the only way of doing this. SQL Server, PostgreSQL and DB2 use the same syntax (even though, as far as I know, there is no ANSI standard syntax for adding comments to database objects).
MySQL supports the way you would like it to work. I agree it would be a nicer mechanism, but in my experience so few people use comments at all that I doubt Oracle will ever change it.
I'm afraid it can only be done after table creation, using the comment on column ... is '' syntax.
A workaround to this annoying syntax is also to view and edit the tables in Oracles SQLExplorer. It contains a wizard that allows you to edit the comments right next to the columns. It even allows easy creation of alter table scripts.
My procedure when editing tables is to enter the changes in the wizard without actually executing them, then go to its DDL tab and retrieve the SQL from there (as update, not full create script) and press cancel on the wizard. Then I put the created SQL into the SQL script I am writing. Only when I am finished with the script I execute everything; I do never make any changes with the wizard itself.
Test on sqlplus (or similar), but the syntax is as follows:
-- assuming you have privileges
COMMENT ON COLUMN SCHEMA1.TABLE1.COL1
IS 'My comment'
-- then you can double check like this
SELECT * FROM all_col_comments WHERE
(OWNER, TABLE_NAME, COLUMN_NAME)
IN (('SCHEMA1','TABLE1','COL1'));
Note that the comment will now show in SQLDeveloper (or Toad or whatever env you have) until you reopen said table's properties.
Similar syntax can be used to annotate tables, indexes and materialized views. [source: https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_4009.htm]
I understand similar syntax exists for MySQL and others, but it is not proper ANSI. It's very useful, though.
I have a table message in a database that has almost a million rows. It has a externalId column which is varchar(50). The values stored in it are guid but I want to update this column to be uniqueidentifier.
So I think I am going to add a new column which is uniqueidentifier. Copy all the values across to this column and then drop the original column. Then I will rename this column to externalId.
My problem is there are hundreds of stored procs etc and I need to make sure that I don't break anything. I also have to grep through all the code and make changes so that we expect a Guid and not a string. (I am using C#)
Does anyone have some tips or recommendations?
Would I be better do just duplicate this column and not touch the existing column and make any code that does a select on it use the guid column instead of the string (currently it sometimes times-out!). I would also have to update any code then that inserts into this table to also insert a guid...)
I love legacy crap .......................
You could simply
alter table message
alter column externalId uniqueidentifier
The risk is that if any of the values stored in the column are not guids, you'll see an error like:
Conversion failed when converting from a character string to uniqueidentifier.
I would probably approach this like so:
work on a copy
add a new column externalIdGuid of type uniqueidentifier
try to convert all externalId into the new externalIdGuid
If that works, then all your externalId are valid GUID's - in that case you could just simply convert the column to type uniqueidentifier:
ALTER TABLE dbo.Message
ALTER COLUMN externalID uniqueidentifier
The only real hint I can give you is to do it all at once. Don't do this piece meal as you will have problems.
Add the column, copy the values, drop the old column, and rename the new one. Then recompile all of your stored procedures. This will give you a list of problem areas. Fix them all and recompile. If that part looks good, then move on to the code. Being legacy you'll probably find a number of other issues here that you didn't even know about.
The code is going to be the toughest area. Most likely the problems are going to involve runtime errors. Make a test plan that covers absolutely everything and go through it.
I wouldn't do this at all. Yes it would have been better if it had been a Uniqueidentifier to begin with but unless you have a specific problem that can't be overcome without changing it what's the value that you're users are getting.
If you do decide to do it. You can query the sys.procedures. Its better than using syscomments or INFORMATION_SCHEMA.ROUTINES
Well turns out after I put a Non Clustered index on that column its pretty fast. I just selected the query in Sql Server management studio and rught clicked and went 'Analyze Query in Database Engine Tuning Advisor'. It told me that this column needs an index and even generates the SQL script you need to add it :)
CREATE NONCLUSTERED INDEX [IX_message_external_id] ON [dbo].[message]
(
[external_id] ASC
)
INCLUDE ( [message_id],
[message_type_id],
[message_status_id],
[template_id],
[user_id],
[raw_message_body]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
One very quick and safe way to check if you break anything on your dev system is to rename your table the message_legacy and make a view called message which casts externalid to uniqueidentifier. That shouldn't mess with the underlying data but will give you a workable interface to see how your stored procs and other code will behave. Remember to grant the same permissions to this view as you have on the table or you might get errors which are permission related instead of type related, which is what you really want to test.
If you get an acceptable result, then go ahead and change the column definition. Personally, I'd rename the table, create a new table with the column type changed, insert into new_table select * from old_table, then drop the old table.
Good luck!
I've just wasted the past two hours of my life trying to create a table with an auto incrementing primary key bases on this tutorial, The tutorial is great the issue I've been encountering is that the Create Target fails if I have a column which is a timestamp and a table that is called timestamp in the same table...
Why doesn't oracle flag this as being an issue when I create the table?
Here is the Sequence of commands I enter:
Creating the Table:
CREATE TABLE myTable
(id NUMBER PRIMARY KEY,
field1 TIMESTAMP(6),
timeStamp NUMBER,
);
Creating the Sequence:
CREATE SEQUENCE test_sequence
START WITH 1
INCREMENT BY 1;
Creating the trigger:
CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT
ON myTable
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT test_sequence.nextval INTO :NEW.ID FROM dual;
END;
/
Here is the error message I get:
ORA-06552: PL/SQL: Compilation unit analysis terminated
ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformed
Any combination that does not have the two lines with a the word "timestamp" in them works fine. I would have thought the syntax would be enough to differentiate between the keyword and a column name.
As I've said I don't understand why the table is created fine but oracle falls over when I try to create the trigger...
CLARIFICATION
I know that the issue is that there is a column called timestamp which may or may not be a keyword. MY issue is why it barfed when I tried to create a trigger and not when I created the table, I would have at least expected a warning.
That said having used Oracle for a few hours, it seems a lot less verbose in it's error reporting, Maybe just because I'm using the express version though.
If this is a bug in Oracle how would one who doesn't have a support contract go about reporting it? I'm just playing around with the express version because I have to migrate some code from MySQL to Oracle.
There is a note on metalink about this (227615.1) extract below:
# symptom: Creating Trigger fails
# symptom: Compiling a procedure fails
# symptom: ORA-06552: PL/SQL: %s
# symptom: ORA-06553: PLS-%s: %s
# symptom: PLS-320: the declaration of the type of this expression is incomplete or malformed
# cause: One of the tables being references was created with a column name that is one of the datatypes (reserved key word). Even though the field is not referenced in the PL/SQL SQL statements, this error will still be produced.
fix:
Workaround:
1. Rename the column to a non-reserved word.
2. Create a view and alias the column to a different name.
TIMESTAMP is not listed in the Oracle docs as a reserved word (which is surprising).
It is listed in the V$RESERVED_WORDS data dictionary view, but its RESERVED flag is set to 'N'.
It might be a bug in the trigger processing. I would say this is a good one for Oracle support.
You've hinted at the answer yourself. You're using timestamp as a column name but it's also a keyword. Change the column name to something else (eg xtimestamp) and the trigger compiles.
Well, I'm not totally sure about it, but I think this happens because the SQL code used to manipulate and access database objects is interpreted by some interpreter different form the one used to interpret PL/SQL code.
Have in mind that SQL an PL/SQL are different things, and so they are processed differently. So, I think there is some error in one interpreter, just not sure which one is.
Instead of having Oracle maintain a view, use EXECUTE IMMEDIATE (i.e. if 'Rename the column to a non-reserved word' is not an option.
You can execute via EXECUTE IMMEDIATE. IT's not better way but work's and avoid column rename.
In my case rename column will be a caotic way