How to check if a column is already a foreign key? - c#

I have table named Person and column named ID
how to check if ID is already FOREIGN KEY cause I want to make it with this code:
ALTER TABLE Person ADD FOREIGN KEY(ID) REFERENCES Job(ID)
ON DELETE CASCADE ON UPDATE CASCADE
but if ID is already a FOREIGN KEY it gives me the following error "may cause cycles or multiple cascade paths" because of the condition with two cascades... How to check if this field is FOREIGN KEY to avoid this error?

You'd want to look in the INFORMATION SCHEMA views
Though it's not as complete as it should be. This is the final query you'd want:
SELECT
KCU1.CONSTRAINT_NAME AS 'FK_CONSTRAINT_NAME'
, KCU1.TABLE_NAME AS 'FK_TABLE_NAME'
, KCU1.COLUMN_NAME AS 'FK_COLUMN_NAME'
, KCU1.ORDINAL_POSITION AS 'FK_ORDINAL_POSITION'
, KCU2.CONSTRAINT_NAME AS 'UQ_CONSTRAINT_NAME'
, KCU2.TABLE_NAME AS 'UQ_TABLE_NAME'
, KCU2.COLUMN_NAME AS 'UQ_COLUMN_NAME'
, KCU2.ORDINAL_POSITION AS 'UQ_ORDINAL_POSITION'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
ON KCU2.CONSTRAINT_CATALOG =
RC.UNIQUE_CONSTRAINT_CATALOG
AND KCU2.CONSTRAINT_SCHEMA =
RC.UNIQUE_CONSTRAINT_SCHEMA
AND KCU2.CONSTRAINT_NAME =
RC.UNIQUE_CONSTRAINT_NAME
AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION
See here for more information
http://msdn.microsoft.com/en-us/library/aa175805(v=sql.80).aspx

Here is a simple little version
SELECT TOP(1) a.COLUMN_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS b JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE a ON a.CONSTRAINT_CATALOG = b.CONSTRAINT_CATALOG AND a.CONSTRAINT_NAME = b.CONSTRAINT_NAME WHERE a.COLUMN_NAME = *your column*)
You can easily add table name and DB name in the where clause as well

Related

How to delete rows from multiple tables using SQL query in asp.net? [duplicate]

I have two tables in MySQL
#messages table :
messageid
messagetitle
.
.
#usersmessages table
usersmessageid
messageid
userid
.
.
Now if I want to delete from messages table it's ok. But when I delete message by messageid the record still exists on usersmessage and I have to delete from this two tables at once.
I used the following query :
DELETE FROM messages LEFT JOIN usersmessages USING(messageid) WHERE messageid='1' ;
Then I test
DELETE FROM messages , usersmessages
WHERE messages.messageid = usersmessages.messageid
and messageid='1' ;
But these two queries are not accomplishing this task .
Can't you just separate them by a semicolon?
Delete from messages where messageid = '1';
Delete from usersmessages where messageid = '1'
OR
Just use INNER JOIN as below
DELETE messages , usersmessages FROM messages INNER JOIN usersmessages
WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'
DELETE a.*, b.*
FROM messages a
LEFT JOIN usersmessages b
ON b.messageid = a.messageid
WHERE a.messageid = 1
translation: delete from table messages where messageid =1, if table uersmessages has messageid = messageid of table messages, delete that row of uersmessages table.
You should either create a FOREIGN KEY with ON DELETE CASCADE:
ALTER TABLE usersmessages
ADD CONSTRAINT fk_usermessages_messageid
FOREIGN KEY (messageid)
REFERENCES messages (messageid)
ON DELETE CASCADE
, or do it using two queries in a transaction:
START TRANSACTION;;
DELETE
FROM usermessages
WHERE messageid = 1
DELETE
FROM messages
WHERE messageid = 1;
COMMIT;
Transaction affects only InnoDB tables, though.
The OP is just missing the table aliases after the delete
DELETE t1, t2
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t1.id = some_id
You have two options:
First, do two statements inside a transaction:
BEGIN;
DELETE FROM messages WHERE messageid = 1;
DELETE FROM usermessages WHERE messageid = 1;
COMMIT;
Or, you could have ON DELETE CASCADE set up with a foreign key. This is the better approach.
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE child (
id INT, parent_id INT,
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);
You can read more about ON DELETE CASCADE here.
no need for JOINS:
DELETE m, um FROM messages m, usersmessages um
WHERE m.messageid = 1
AND m.messageid = um.messageid
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'
Try this please
DELETE FROM messages,usersmessages
USING messages
INNER JOIN usermessages on (messages.messageid = usersmessages.messageid)
WHERE messages.messsageid='1'
Try this..
DELETE a.*, b.*
FROM table1 as a, table2 as b
WHERE a.id=[Your value here] and b.id=[Your value here]
I let id as a sample column.
Glad this helps. :)
You can also use like this, to delete particular value when both the columns having 2 or many of same column name.
DELETE project , create_test FROM project INNER JOIN create_test
WHERE project.project_name='Trail' and create_test.project_name ='Trail' and project.uid= create_test.uid = '1';
there's another way which is not mentioned here (I didn't fully test it's performance yet), you could set array for all tables -> rows you want to delete as below
// set your tables array
$array = ['table1', 'table2', 'table3'];
// loop through each table
for($i = 0; $i < count($array); $i++){
// get each single array
$single_array = $array[$i];
// build your query
$query = "DELETE FROM $single_array WHERE id = 'id'";
// prepare the query and get the connection
$data = con::GetCon()->prepare($query);
// execute the action
$data->execute();
}
then you could redirect the user to the home page.
header('LOCATION:' . $home_page);
hope this will help someone :)
Thanks

Get Foreign keys in the table

I created one script to display the foreign keys in the particular table.
SELECT i.CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON
i.CONSTRAINT_NAME = k.CONSTRAINT_NAME WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_NAME = 'sample';
When I execute this command in my host, it displays the list of foreign key constraints found in all the databases with table name "sample".
But i need particular database, sample table foreign keys.
just add at the end
AND i.table_schema = '<the name of your database which is a schema>'
EDIT :
Change the left join to
LEFT JOIN information_schema.KEY_COLUMN_USAGE
ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND
i.TABLE_SCHEMA = k.TABLE_SCHEMA
because you could find constraint with same name in different schemas.
what's a schema and a database in mysql
Need to select the database before run this query. Following may be helpful.
USE YourDatabaseName
SELECT i.CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k
ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_NAME = 'sample'

How to get Primary and foreign Key details from MS Access database

I need a query or C# code to get the primary key or foreign key details of each table in an MS Access database.
Try OleDBConnection.GetSchema
Additional information : Retrieving Database Schema Information (ADO.NET)
1. SELECT * FROM ALL_CONS_COLUMNS A
JOIN ALL_CONSTRAINTS C ON A.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE C.TABLE_NAME = <your table> AND C.CONSTRAINT_TYPE = 'P'
2. SELECT * FROM ALL_CONS_COLUMNS A
JOIN ALL_CONSTRAINTS C ON A.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE C.TABLE_NAME = <your table> AND C.CONSTRAINT_TYPE = 'R'
1st is for primary key & 2nd one is for foreign key..........I think this may help you.

Fluent NHibernate join not using primary key

I am trying to get a single property from a joined table where a non-PK in my main table is joined to the PK of the foreign table. Below is an oversimplified example of what I am trying to accomplish (I do not want to reference the foreign entity):
Tables:
CREATE TABLE Status
(
Id int,
Body text,
CategoryId int
)
CREATE TABLE Category
(
Id int,
Name text
)
SQL to generate:
SELECT Id, Body, CategoryId, Category.Name AS CategoryName
FROM Status
LEFT JOIN Category ON Category.Id = Status.CategoryId
I am trying to map the join like this in the StatusMap but it seems to be joining on the two primary keys (where Status.Id = Category.Id):
Join("Category" m =>
{
m.Optional();
m.KeyColumn("CategoryId");
m.Map(x => x.CategoryName, "Name");
});
As far as I know the only way around this using Fluent is to map to a view as you currently are doing. Join() will always map to the primary key of the parent table. The KeyColumn method specifies the key column for the child table only, which in your case is the Category table.
To achieve the desired SQL using your simplified version above you'd probably want to use References to define a many-to-one relationship between status and category.

How to handle mututally/recursively related tables?

I'm pretty new to databases and sql. I have a problem where I have two tables which both contain a foreign key to the primary key of the other. My problem is I have a large number of elements which can have multiple names in different languages, but MUST have a single primary name/language.
alt text http://img688.imageshack.us/img688/1121/11768540.png
Firstly, I want to know if this is possible, or should I just give up already? The obvious solution is to have an extra boolean field in the ElementName table to say IsDefaultName, but it adds some extra complexity for querying and updating. If this is the best solution, how do I constrain the ElementName table to not accept any submission if IsDefaultName is set and the table already has an entry with the same ElementId and IsDefaultName set (or would I need to query this manually)?
I'm attempting to use LINQ to SQL here. The code I'm using to attempt to insert new items throws an exception at SubmitChanges with The INSERT statement conflicted with the FOREIGN KEY constraint "FK_ElementName_Element". I can understand why this is, but wondering if there's a fix/better solution.
var db = new MyDBDataContext();
var element = new Element();
var elementName = new ElementName() {
ElementName1 = "MyElement",
Language = "English",
};
element.ElementName = elementName;
db.Elements.InsertOnSubmit(element);
db.ElementNames.InsertOnSubmit(elementName);
db.SubmitChanges();
Solution 1
element
------------------
element_id
~....
element_name
------------------
element_name_id
fk_element_id
name
language_id
is_default_name Default ( 0 )
Trigger:
if ( ( select count ( 1 ) from element_name where is_default_name = 1 ) > 1 )
BEGIN
raisError ( 'only 1 element_name may be marked is_default_name = true.', 16, 1 );
END
Solution 2
element
------------------
element_id ( pk )
~....
element_name
------------------
element_name_id ( pk )
fk_element_id
name
language_id
element_name_default
------------------
fk_element_id
fk_element_name_id
( pk - fk_element_id, fk_element_name_id )
Solution 3
element
------------------
element_id
fk_element_name_id_default NULL
~....
element_name
------------------
element_name_id
fk_element_id
name
language_id
order of code:
* Insert to element_name
* update of element
I would stick with what you had, cause it is just fine, just:
db.Elements.InsertOnSubmit(element);
db.ElementNames.InsertOnSubmit(elementName);
//I don't know this syntax to say
// set the property of element.fk_element_name_id_default
// to the newly inserted elementName from above
db.Elements.?.?
Why not simply use a self-join like so:
Create Table Elements(
ElementId... Not Null Primary Key
, DefaultElementId ... Not Null
References Elements( ElementId )
, Name ...
, Language ...
)
The default name is the one where ElementId = DefaultElementId.
Btw, this is a place where a guid PK is nicer than an identity column. With a guid PK, you could generate both the ElementId and DefaultElementId from the client. If you are using an identity column with this schema, you'll probably have to create a "Unknown" elementId with a known value like zero so that you can do the insert and then turn around and do an update all in a single transaction.
** ADDITION **
Given what you said in comments, it sounds like you are trying to localize the elements data. My inclination would be to recommend adding a non-nullable "Name" column to the Elements table which represents the language neutral or default language name. Your ElementNames table would have a foreign key to the Elements table and would only populate that table when you localized an element name. Your queries would then need to coalesce on the requested language name and the name in the elements table if the requested language did not have a localized name.

Categories

Resources