hi i have a problem when adding unique constraint creation to my change log. in logs it shows the liquibase is reading change sets but i still cant find the unique constraint through query . the problem is it is only applied when i recreate database it doesn't work if table exists before.
<changeSet id="20220524-1" author="Saba Mosleh">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">
SELECT DISTINCT count(CONSTRAINT_NAME) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE
TABLE_NAME = 'voucher_codes' AND CONSTRAINT_TYPE = 'UNIQUE' and CONSTRAINT_NAME = 'unique_voucher_code';
</sqlCheck>
</preConditions>
<addUniqueConstraint tableName="voucher_codes" columnNames="code" constraintName="unique_voucher_code"/>
</changeSet
a table DATABASECHANGELOG is created by liquibase delete your changelog record so liquibase will execute your change log when you restart the application,
or simply add
<addUniqueConstraint
tableName="voucher_codes"
columnNames="code"
constraintName="unique_voucher_code"
runAlways="true"/>
to execute the statement every time.
I started to get this error after marking an ID column on an entity with DatabaseGeneratedOption.Identity (for some reason EF didn't know it was an identity column and was trying to insert a value on that column).
I found this question: A dependent property in a ReferentialConstraint is mapped to a store-generated column.
However, as far as I can tell, all of my relations are perfectly fine. I checked every single table, and triple checked the tables related to the one on which I added the DatabaseGeneratedOption.Identity to. Even odder, the column mentioned in the error is 'ID' - I don't have any foreign keys where the dependent column is ID. I checked this using the following query, which returned no column named 'ID':
SELECT Tab.TABLE_NAME, Col.Column_Name from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type = 'FOREIGN KEY '
Is there anyway to determine which table has the offending foreign key, if indeed it exists? Is there a query I can run to determine if a column marked as 'Identity' is also the dependent column in a foreign key relationship?
Using Hibernate ORM against SQL Server 11 on ColdFusion 10.
I'm getting the error:
[Macromedia][SQLServer JDBC Driver][SQLServer]The ALTER TABLE
statement conflicted with the FOREIGN KEY constraint
"FK9E8E5409B9A80FE4". The conflict occurred in database "dbname", table
"dbo.TableName", column 'TableId'.
Which seems self-explanatory, except I have checked the relevant table in SQL Server Management Studio and don't find a foreign key constraint with that ID for that table, nor any related tables.
Is there a way to locate the constraint, e.g. by querying the database system tables?
Update: I was looking in the wrong system views - looking inside dbname.sys.foreign_keys I do see a bunch of foreign keys, but checking for the one mentioned in the error returns nothing. Is that the right place to look?
Take a look at the sys.all_objects view, it's easier to query
select
sa.name as FKName
,so.name as TableName
from
sys.all_objects sa
inner join sys.objects so on sa.parent_object_id = so.[object_id]
where
sa.[type] = 'F'
Now that we've ran out of int capacity on a PK column (which is an IDENTITY) I'd like to do this to bigint, but simple ALTER TABLE seems to be unable to handle that big of a table. So my question is: how do I change the type of a PK column with keeping actual values in place and do I need to alter referencing tables as well?
In addition to KLE's suggestion, the following queries might help:
To disable all constraints on the tables that reference oldTable try to execute the output of the following query:
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
To move all data into the new table, with alteration of the field try this:
INSERT INTO newTable
SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN
FROM oldTable
To drop the old table:
DROP TABLE oldTable
To rename the new table to the old name:
sp_rename newTable, oldTable
To reenable all the constraints on the tables that reference oldTable, try to execute the output of the following query:
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
Hope it helps...
What we would do is:
save your table
create a new table with the correct structure
disable all constraints on these tables, and the ones that reference them
move all data into the new table, with alteration of the field ; it can be done by batches
delete the old table when it's empty
rename the new table to the old name
enable all constraints on all tables (some FK column and constraints probably need fixing too... But they are not PK, so they are modifiable)
6 edited (thanks to Alexey)
This is clean, doable in batches, well understood.
You will need to also alter the child tables. After all you will now be trying to insert a big int into them as well. I would change over the child tables first
This is not an easy or short process. I would suggest to you that you tell your users the the database is going to be down for maintenance (you can gauge how long by how long it takes to do dev) on a set date and reset the databse to single user mode while you make these changes. You don't want to lose data that is added (or changed)by users to one table while you are switching to the other one. if for somereason you can't havea maintence window (and I strongly suggest for the sake of data integrity that you do), then you must change the child tables over first to avoid insert errors if your a really close to the limit and will be seeing the large numbers almost immediately.
Make sure to script the entire datbase structure including defaults, triggers, check constrants indexes etc as you will want to recreate everything.
Make sure to do all this through scripts on dev. That will make it much easier to do one prod once you have tested the process out.
I'm think you can only create a new database with changed PK datatype, and then export/import data, or bulk insert into new, then rename new database. Of course this actual if you have many referenced tables and your new PK datatype not compatible with previous.
I have a table with a unique constraint on one or more fields. Given the constraint name, I want to query the system views to get the list of fields that are part of this constraint.
SQL Server 2005.
Thanks.
Look at information_schema.constraint_column_usage
select column_name from information_schema.constraint_column_usage
where constraint_name = 'your constraint'