I'm trying to create a table from an existing table. What are the other constraints that are passed apart from the NOT NULL constraints? Also what are the other attributes/features passed to the new table?
The query that I use to create the new table is this:
create table sales_emp
as
select * from emp;
The following information can be found in the official manual (all the emphases are mine):
Oracle Database derives datatypes and lengths from the subquery. Oracle Database follows the following rules for integrity constraints and other column and table attributes:
Oracle Database automatically defines on columns in the new table any NOT NULL constraints that were explicitly created on the corresponding columns of the selected table if the subquery selects the column rather than an expression containing the column. If any rows violate the constraint, then the database does not create the table and returns an error.
NOT NULL constraints that were implicitly created by Oracle Database on columns of the selected table (for example, for primary keys) are not carried over to the new table.
In addition, primary keys, unique keys, foreign keys, check constraints, partitioning criteria, indexes, and column default values are not carried over to the new table.
If the selected table is partitioned, you can choose whether the new table will be partitioned the same way, partitioned differently, or not partitioned. Partitioning is not carried over to the new table. Specify any desired partitioning as part of the CREATE TABLE statement before the AS subquery clause.
Related
I have multiple tables with a unique column name for each of their primary key such as: DeviceName, DeviceNumber, SwitchNumber, Etc.
There is another table which serves as an audit trail containing the changes from all tables, it lists the table name and the primary key value for each respective table as a reference i.e.
Table#2
TableName, InstanceNumber
I would like to use the information in table #2 to pull the respective records from each table in 'TableName' by referencing the 'InstanceNumber' attribute as the PK for each respective table without having to manually create a reference for each table's column name.
Is there a way I can do this? That is, create a query that references a 'general' column name to a table that points to the primary key column?
Select * from (TableName) where (PrimaryKeyColumn) = (InstanceNumber);
You can only do this using dynamic SQL -- in PL/SQL, that would be execute immediate.
Why not? Here is one reason. All the columns returned by a query need to be known when the query is compiled. That is, before any data is read. You are requesting a set of columns that depends on the table that is in the data. So, the columns are NOT known and the query cannot be compiled.
I'm currently working on a simple dummy project to refresh my knowledge on SQL and to learn a few new things :)
I have a table Article with the columns:
aID, price
I have another table Storage:
sID, aID, count
The Storage table references the aID as a foreign key and the count column say how much of an article is stored.
Now I want to add a column value to my Storage table. This column should be calculated by Article.price * Storage.count.
I found after searching the web that you can have calculated columns like this
CREATE TABLE tbl
(
int1 INT,
int2 INT,
product BIGINT GENERATED ALWAYS AS (int1 * int2) STORED
);
But I haven't found an example how to this with columns from another table.
What do I have to do in order to use the price from the referenced aID in the calculation?
You cannot define a generated column based on values from other tables. Per the documentation:
The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.
You can achieve the expected behavior by creating two triggers on both tables but usually creating a view based on the tables is a simpler and more efficient solution.
I have a code list table with a group name and key id. Instead of using discreet tables for every look-up (key/description pair), they are all in a single code_list table. I would like to generate a FK using a literal and column name as the relational key.
Example:
Order table -> "State" & order.state_id -> code_list.group_name & code_list.key_id.
The statement below, obviously does not work, but is an example of what I am trying to accomplish.
ALTER TABLE [dbo].[Order] WITH CHECK
ADD CONSTRAINT [FK_State_Code_List]
FOREIGN KEY('State', [State_Id])
REFERENCES [dbo].[Code_List] ([Group_Name], [Key_Id])
I am using SQL Server 2014
You can't use a literal value.
You could add a persisted computed column with the desired value and reference that in the FK definition, used in some super type / sub type models as this questioner demonstrates.
But you appear to be implementing the "one true lookup table" anti pattern here.
You should just have a separate table for State and a regular foreign key.
For a given table and the unique ID of one record in that table, what's the easiest/quickest to generate a PL/SQL (or SQL) script that creates a copy of that record, then creates copies of all records from tables with a foreign key relationship to that record, and then all tables with a foreign key relationship to those 2nd tier records, and so on until all related records in all directly or indirectly related tables in the schema have been copied?
Such a script would be useful in capturing and reproducing the state of a record and all descendant records for testing purposes.
Considerations:
Schema has 500+ tables so writing this script manually would be slow.
Avoid unique constraint violations by ensuring that the new records have their own generated/altered primary key values. Generate new IDs using max(id_column) + 1 rather than sequence, to simplify problem.
Use Oracle metadata tables to gather list of tables, and maybe primary key and foreign key columns (?).
Thanks.
Assuming the FKs are present and valid, you would drive this from dba_constraints, starting with r_constraint_name = the PK constraint of the start table. For each table found, you would query dba_tab_columns and build your queries and generated inserts from here. You would do this recursively to capture all the tables in the tree. To make it easier, I would generate a stored procedure table_ins wrapper, so that when you generate you INSERT you instead call the store_proc to avoid having to generate the INSERT ( col1, .... ) for each row.
There is one column named Line_no (smallint) now. I want to change this column data type is bigint ,but this column is primary key, and have so many tables has foreign key reference on it, so how to change it?, i need to change both Sql server and oracle database
First of all there's no easy way to do that currently. especially in Oracle, in order to change the data type, all the values of the field should be null. anyway the following process works for both Oracle and SQL Server:
make your database off line so that no operation can disturb our
process.
Add a new field, say line_num having your new data type.
update the the new field with the line_no values for all records.
write a Stored Procedure to drop all the FKs referencing current
PK, using meta data and this SP should write the add FK command to
dbms output, while it is looping, so that later you can execute them
to add these FKs again in step 9.
drop the primary key off the line_no field.
drop the field line_no.
rename the field
line_num to line_no.
add the primary key on the new field.
run the commands generated in step 4 to add all the FKs again.
make your db online :)
It depends on your DBMS. You may have to drop the foreign key constraints, alter the columns and re-create the constraints.