Dependency in SQL - sql-server

In SQL, I've to delete a data from table A which is dependent on table B.
The data to be deleted should satisfy two conditions WorkArea='123' and FileNo='45'.
Table B has WorkArea but it does not contain data for FileNo.
And Table A contains the record satisfying both the conditions.
There isn't any reference key. For more clarity, adding a query here:
Select * from table A where WorkArea='123' and FileNo='45';
This will generate the resulting record. But as it is dependent on Table B, I cannot delete it directly. Also, to delete it from table B isn't possible because data in WorkArea is a whole and it contains many files and I have to delete a specific File.
So how can I delete data from table A?
This is Table A with col1 and col2 as primary key.
This is Table B with col1 as a primary key.

If you have no Foreign Keys, the following sentence will work.
DELETE FROM [A] WHERE [WorkArea] = '123' AND [FileNo] = '45';
Then you can programmaticaly check if there are "orphans" on table B with the following request :
SELECT DISTINCT [B].[WorkArea]
FROM [B]
LEFT JOIN [A]
ON [A].[WorkArea] = [B].[WorkArea]
WHERE [A].[WorkArea] IS NULL
To enhance this last part and produce a DELETE sentence from it, just store the result of this request into a temporary table then use it as a WHERE statement with the IN keyword.

Related

SQL Server Insert If Not Exists - No Primary Key

I have Table A and Table B.
Table A contains data from another source.
Table B contains data that is inserted from Table A along with data from other tables. I have done the initial insert of data from A to B but now what I am trying to do is insert the records that do not exist already in Table B from Table A on a daily basis. Unfortunately, there is no primary key or unique identifier in Table A which is making this difficult.
Table A contains a field called file_name which has values that looks like this:
this_is_a_file_name_01011980.txt
There can be duplicate values in this column (multiple files from the same date).
In Table B I created a column data_date which extracts the date from the table a.file_name field. There is also a load_date field which just uses GETDATE() at the time the data is inserted.
I am thinking I can somehow compare the dates in these tables to decide what needs to be inserted. For example:
If the file date from Table A (would need to extract again) is greater than the load_date of Table B, then insert these records into Table B.
Let me know if any clarification is needed.
You could use exists or except. With the explanation here it seems like except would make short work of this. Something like this.
insert tableB
select * from tableA
except
select * from tableB

Merging SQLite3 tables with identical primary keys

I am trying to merge two tables with financial information about the same list of stocks: the first is the prices table (containing, daily, weekly, monthly, etc... price data) and the second is the ratios table (containing valuation and other ratios). Both tables have identical primary key numerical ID columns (referencing the same stock tickers). After creating a connection cursor cur, My code for doing this is:
CREATE TABLE IF NOT EXISTS prices_n_ratios AS SELECT * FROM
(SELECT * FROM prices INNER JOIN ratios ON prices.id = ratios.id);
DROP TABLE prices;
DROP TABLE ratios;
This works fine except that the new prices_n_ratios table contains an extra column named ID:1 whose name is causing problems during further processing.
How do I avoid the creation of this column, maybe by somehow excluding the second tables's first primary key ID column from * (listing all the column names is not an option), or if I can't, how can I get rid of this extra column from the generated table as I have found it very hard to delete it in SQLite3?
Just list all the columns you actually want in the SELECT clause, instead of using *.
Alternatively, join with the USING clause, which automatically removes the duplicate column:
SELECT * FROM prices JOIN ratios USING (id)

SQL Server get delta items

I have a many-million-records table having an integer primary key defined.
I also have a not-so-many-million IDs that are in the "black list". They are stored in memory (read from a file on disk).
I have to select the records that are NOT in the black list, that is, all the records whose ID is not in my black list.
I solved this using a temp table (single column: ID) to insert the unwanted IDs then select all records whose IDs are not in this table.
My main concern is performance:
Inserting so many record in temp table.
Selecting the item not being in temp table.
EDIT
At the moment I use a temp table like this:
create the temp table with a single column (ID)
fill the temp table with IDs
create a nonclustered index on column
get the delta items with a query similar to this:
select m.id from mytable m where m.id not in (seelct id from #tempTable)
The best option you have here is to add a column to flag each row whether it is blacklisted or not ( ex: call it isBlockListed), and keep this column up-to-date.
You can also add an unclustered index to this flag so you can quickly select your data where isBlockListed = ture / false.

Foreign Key fails to create

I want a foreign key between 2 tables , so i try it like i always do. Now the issue i'm having is he fails to create , and by the looks of it it fails to create because there is already a key but there isnt.
- Unable to create relationship
'FK_tbl_Paramed_RegistratieBehandelingen_Users'.
The ALTER TABLE statement conflicted with the
FOREIGN KEY constraint "FK_tbl_Paramed_RegistratieBehandelingen_Users".
The conflict occurred in database "Nestor_Server",
table "dbo.Users", column 'UserID'.
Ive checked if they have the same type , they do(bigint) so don't get why he won't create it
It is possible that you have records in RegistratieBehandelingen(Not sure about the table name) which is not present in Users Table.
select * from RegistratieBehandelingen a where UserID IS NULL or
not exists (select 1 from Users b where b.UserID= a.UserID)
This means that you have child data with no matching parent ID.
Run the following to see if you get any results:
SELECT *
FROM tbl_Paramed_RegistratieBehandelingen r
LEFT JOIN Users u on r.UserID = u.UserID
WHERE u.UserID IS NULL
(changing table and column names where appropriate)
If you get any results then it should show which records contains UserIDs that don't match to Users.
After the above query, you may want to delete non existing UserId from table tbl_Paramed_RegistratieBehandelingen or insert them in table Users .

How to insert a new record to table A when table A deppends on table B and vice versa

I'm not sure if this is well designed, if it's not please, advice me on how to do this.
I'm using Sql Server 2008
I have:
TableA (TableA_ID int identity PK, Value varchar(10), TableB_ID PK not null)
TableB (TableB_ID int identity PK, Value varchar(10), TableA_ID PK not null)
The goal is simple:
TableA can have rows only if there is at least 1 row in TableB associated with TableA;
And for each row in TableB, there must be a row associated with it in TableA);
TableA is the "Parent Table", and TableB is the "Children's table", it's something like, a parent should have 1 or more children, and each child can have only 1 parent.
Is this right?
The problem I'm having is when I try to do an INSERT statement, if this is correct, how should I make the INSERT? temporary disable the constraints?
Thanks!
The problem I'm having is when I try to insert
TableA (TableA_ID int identity PK, Value varchar(10))
TableB (TableB_ID int identity PK, Value varchar(10), TableA_ID not null)
as a parent, table a does not need to reference table b, since table be requires there be a field in table a. this is called a one to many relationship.
so in table a you might have these values:
1 a
2 b
3 c
and in table b you could have these:
1 asdf 1
2 sdfg 1
3 pof 2
4 dfgbsd 3
now you can make a query to show the data from table a with this:
select b.TableB_ID, b.Value, a.TableA_ID, a.Value
from TableB b
inner join TableA
on b.TableA_ID=a.TableA_ID
The parents don't depend on the children. You need to remove your reference to Table B in Table A.
You have a circular dependency. These don't really work well for declarative enforcement, you would have to disable the constraints every time you wanted to insert.
That's an unusual requirement. If I was stuck with it (and I would really push back to make sure it was indeed a requirement) I would design it this way:
Make a regular foreign key from table a to table b with a the parent and b the child.
Add a trigger to table a that inserts a record to table b if one does not exist when a table a record is inserted. Add another trigger to table b that deletes the table a record if the last related record in table b is deleted.
ALternatively, you could put the inserts to both tables ina stored proc. Remove all insert rights to the table except through the proc. YOu would still need the foreign key relationship from tablea to table b and the trigger on table b to ensure that if the last record is deleted the table a record is deleted. But you could do away with the trigger on table a in this case.
I would use the first scenario unless there is information in table b that cannot be found from the trigger on table a, say one or more required fields that don't have a value you can figur eout form table a.
I would put the inserts into a proc: disable the constraints, insert the data, enable the constraints. You may need to make sure that this is the only transaction going on whilst the constraints are disabled though.
That could be acheived by making the isolation level SERIALIZABLE, but that in turn could massace your concurrency.
Kev

Resources