Inserting null values when using bulk insert - sql

I have one table:
CREATE TABLE cust (
cust_id NOT NULL,
cust_name NOT NULL,
address NULL
);
I have to insert these rows into another table:
CREATE TABLE 1cust_det (
cust_id NOT NULL,
cust_name NOT NULL,
address NOT NULL
);
Unfortunately the cust.address column contains NULL values. I want to insert these rows from cust to 1cust_det using a cursor. What do I have to do?

INSERT INTO
cust_det
SELECT
cust_id,
cust_name,
COALESCE(address, 'UNKNOWN')
FROM
cust

If you have access to change the destination table, just add a default to the column.
CREATE TABLE 1cust_det (
cust_id NOT NULL,
cust_name NOT NULL,
address NOT NULL DEFAULT 'DEFAULT_VALUE');
or if you can edit the existing destination table and it doesnt get drooped
ALTER TABLE 1cust_det
ALTER address SET DEFAULT 'DEFAULT_VALUE'
The easiest way if you don't have control of the destination table to add a default value to the address column is to use a case statement in the insert itself. In the example below you can also use a ISNULL evaluation, but you might want to search for empty strings as well. Please try to find a better way to insert instead of using a cursor.
INSERT dbo.1cust_det
(cust_id,cust_name,[address])
SELECT cust_id,cust_name,
CASE
WHEN [address] IS NULL THEN 'some default value'
ELSE [address]
END AS [address]
FROM cust

Above answers are correct. You may have another table that may have address for cust_id. Join that table to get missing address. I have seen that in almost all databases, address is stored for every customer. You must get address where address is NULL in the table cust.

Related

How do I select insert into select a table which already has values in the primary key column without adding new rows?

I'm working on a database for my school project in which I have to produce a functional database by normalizing sample tables given to us.
One table I'm having trouble with is itineraries. I produce 3 tables from the normalization which are "Destinations", "Itineraries" and "Itinerary_Destinations".
The code for Destinations is:
create table Destinations
(
DestinationID varchar(5) primary key,
Name varchar(45)
);
The code for Itineraries is:
create table Itineraries
(
ItineraryID varchar(5),
Name varchar(45)
);
The code for the last table is:
create table Itinerary_Destinations
(
DI varchar(5) primary key,
ItineraryID varchar(5) foreign key references Itineraries(ItineraryID),
Itinerary_Name varchar(45),
DestinationID varchar(5) foreign key references Destinations(DestinationID),
Destination_Name varchar(45)
);
Data has already been inserted into all 3 tables with the exception of 'Destination_Name' and 'Itinerary_Name' columns. The code I'm attempting to use is returning as error. The code is shown below.
insert into Itinerary_Destinations (Itinerary_name)
select Name from Itineraries where
Itineraries.ItineraryID = ItineraryID;
The error it returns is
Msg 515, Level 16, State 2, Line 1 Cannot insert the value NULL into
column 'DI', table 'DDDAssignment.dbo.Itinerary_Destinations'; column
does not allow nulls. INSERT fails. The statement has been terminated.
Is there a method to accomplish the task of inserting the Destination_Name and Itinerary_Name without creating new records that require primary keys?
Or should I do it manually?
If you want to modify records which already exist, then you should be using an UPDATE rather than an INSERT:
UPDATE a
SET Itinerary_name = b.Name
FROM Itinerary_Destinations a
INNER JOIN Itinerary_name b
ON a.ItineraryID = b.ItineraryID;
But, if you do have some data which is not already logically associated with the Itinerary_Destinations table, then using an insert is appropriate.
use coalesce funtion in case null it will insert blank string, as your column does not allow null value thats why you got that error in your query
insert into Itinerary_Destinations (Itinerary_name)
select coalesce(Name,' ') from Itineraries where
Itineraries.ItineraryID = ItineraryID;

SQL sever constraint data

I have 2 table Product and Supplier
create table Product(
ProductCode int not null primary key,
Name varchar(50) not null ,
PurchasePrice numeric(20,3) not null,
SellPrice numeric(20,3) not null ,
Type varchar(50) not null,
SupplierCode int not null
)
go
create table Supplier(
SupplierCode int not null primary key,
SupplierName varchar(50) not null ,
Address varchar(50) not null
)
I want : A product of Samsung must be television, mobile or tablet.
Help me.
database enter image description here
I want "SupplierCode<>4" because Supplier supply 'food'
You can't achieve it this way do something like this in check constraint because value depends on different tables.
The most straightforward way would be to create a trigger. This one is after insert. It just deletes rows that are not acceptable. You can experiment and make it instead of insert instead
CREATE TRIGGER insertProduct
ON Sales.Product
AFTER INSERT, UPDATE
AS
delete from inserted a
join Supplier b on a.SupplierCode = b.SupplierCode
where
(b.Supplier = 'Samsung' and a.Type not in ('phone', whatever you need...))
or (b.Supplier = 'different' and a.Type not in (...))
--here you put any additional logic for different suppliers
if ##ROWCOUNT > 0
RAISERROR ('Couldn't insert into table', 16, 10);
GO
Depending on your case what you can also do is make inserting to the tables available only via stored procedures. Then put the checks in the stored procedure instead.
If I understand you correct, you want to define for each suppliers what kind of products are allowed in your tables.
I think you need a table that defines what producttypes are allowed for what Suppliers, and than you can force this in a trigger or in your client.
First you need a table to define the kind of products
table ProductType (ID, Name)
this holds info like
(1, 'Television'), (2, 'Tablet'), (3, 'Mobi'), (4, 'Food'), and so on...
Then replace the field Type by ProductTypeID in your Product table
Now you can have a table that defines what product types each supplier may have
table AllowedProducts (ID, SupplierCode, ProductTypeID)
and finally you can check this in your client, or in a trigger if you want to keep this rule in your database
When inserting data you can check if the ProductTypeID of the selected Product is present in table AllowedProducts for the selected ´Supplier` and if not reject the insert.

Adding new NOT NULL column to existing database

Lets say I have a system that has a person table:
CREATE TABLE Person
(
FirstName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
DOB DATE NOT NULL
)
If we want to update the system after it has been in place for a number of years and we now want to also capture the person's address (by means of a new NVARCHAR column called Address which is NOT NULL)
Therefore we want all new records to be NOT NULL but we don't have any data for the old records so they would have to be NULL
What is the best way to do this? We cannot add a NOT NULL column because it would be NULL for all the existing records.
Is the best way to add the column and allow NULLS, add some placeholder value (EG '.') to the existing records, then alter the column to be NULL?
Or is there some other way to do it?
You cannot add a new NOT NULL column without assigning non-NULL values to existing rows (via a default constraint). However, you can add a NULL column and ensure only NOT NULL values going forward by specifying a check constraint that prohibits NULL values along with the NOCKECK option so that existing data are not validated:
CREATE TABLE dbo.Person
(
FirstName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
DOB DATE NOT NULL
)
INSERT INTO dbo.Person (FirstName, LastName , DOB)
VALUES(N'foo', N'bar', '20010101');
GO
--add new column and CHECK constraint with NOCHECK
ALTER TABLE dbo.Person WITH NOCHECK
ADD Address nvarchar(50) NULL
CONSTRAINT CK_Person_Address CHECK (Address IS NOT NULL);
GO
--this fails due to check constraint violation
INSERT INTO dbo.Person (FirstName, LastName , DOB)
VALUES(N'foo2', N'bar2', '20020101');
GO
--this succeeds
INSERT INTO dbo.Person (FirstName, LastName , DOB, Address)
VALUES(N'foo2', N'bar2', '20020101', N'non-null address');
GO
This method provides the proper NULL semantics for existing persons that have no addresses yet guarantee the desired data integrity for new persons.

oracle error: not enough values

i have a table donor_master:
create table donor_master
(
donor_id number(10) primary key not null,
dob date not null,
age number(3) not null,
gender char(1) not null,
blood_group char(3),
contact_no number(10),
address varchar(50) not null,
city varchar(10) not null,
pin number(10) not null,
state varchar(10) not null,
branch_registration_id number(5) references branch_master(branch_id)
);
when i try to insert into the table in a procedure insert_donor_master, i get "not enough values" error on compilation.
this is the procedure:
create or replace procedure insert_donor_master(
vdob donor_master.dob%type,
vage donor_master.age%type,
vgender donor_master.gender%type,
vblood_group donor_master.blood_group%type,
vcontact_no donor_master.contact_no%type,
vaddress donor_master.address%type,
vcity donor_master.city%type,
vpin donor_master.pin%type,
vstate donor_master.state%type,
vbranch_registration_id donor_master.branch_registration_id%type
)
is
begin
insert into donor_master values (sq_donor_master.nextval, vdob, vage, vgender, vblood_group, vcontact_no, vaddress, vcity, vpin, vstate, vbranch_registration_id);
commit;
end;
What is the problem?
Thanks.
Oracle hurls ORA-00947 when we specify an INSERT statement which doesn't have a value for every column in the table.
Now, the CREATE TABLE statement you posted shows a table with eleven columns. And the stored procedure code you posted shows an insert statement with eleven values in the VALUES (...) clause.
So, the explanations are:
you have a configuration management issue, and you're running the wrong version of the stored procedure or the wrong version of the table
you have a configuration management issue, and the actual structure of the table isn't what you think it is (doesn't match your CREATE TABLE script)
you aren't really getting an ORA-00947 error
Note that if you don't want to populate every row you can specify a projection of the relevant columns before the VALUES clause. For instance, if you just wanted to populate the mandatory columns you would code this:
insert into donor_master
(donor_id, dob, age, gender, address, city, pin, state )
values (sq_donor_master.nextval, vdob, vage, vgender, vaddress, vcity, vpin, vstate)
All that matters is that the number of values matches the number of columns.
The complete syntax for INSERT statements is in the documentation. enter link description hereFind out more.

SQL Server: Extracting a Column Into a Table

I have a table with a column that I want to extract out and put into a separate table.
For example, lets say I have a table named Contacts. Contacts has a column named Name which stores a string. Now I want to pull out the names into another table named Name and link the Contact.Name column to the Id of the Name table.
I can only use SQL to do this. Any ideas on the best way to go about this?
Let me know if I can clarify anything, thanks!
[edit]
One problem is that different contacts can be tied to the same name. So when different contacts have the same name and it gets exported the Name table would only have one unique row for that name and all the contacts would point to that row. I guess this wouldn't make sense if I were actually working on a contact book, but I'm just using it to illustrate my problem.
CREATE TABLE Name (NameID int IDENTITY(1, 1), [Name] varchar(50))
INSERT INTO Name ([Name])
SELECT DISTINCT [Name]
FROM Contact
ALTER TABLE Contact
ADD COLUMN NameID int
UPDATE Contact
SET NameID = [Name].NameID
FROM Contact
INNER JOIN [Name]
ON Contact.[Name] = [Name].[Name]
ALTER TABLE Contact
DROP COLUMN [Name]
Then add foreign key constraint, etc.
Create the new table with a Foreign key that points back to the contact table. Then insert the names and contactids from the contact table into this new table. After that you can drop the "name" column from the contact table.
CREATE TABLE Name
(
ContactId int,
Name nvarchar(100)
);
INSERT Name(Name)
SELECT ContactId, Name From Contact;
ALTER TABLE Contact
DROP Column name;
EDIT: Since you have edited the question to mention that one name can be associated with multiple contacts, this changes things in the opposite way.
CREATE TABLE Name
(
NameId int IDENTITY,
Name nvarchar(100)
);
INSERT Name(Name)
SELECT DISTINCT Name From Contact;
ALTER TABLE Contact
ADD NameId int;
UPDATE c
SET c.NameId = n.NameId
FROM Contact c
JOIN Name n on n.Name = c.Name;
ALTER Table Contact
Drop Column Name;
NOTE: Make sure that you create the appropiate foreign key between the Contact and Name tables using the NameId on the Contact table and also create a UNIQUE constraint on the "name" column in the Name table.
insert into another_table( contact_id, name )
select id, name
from contacts;
insert into new_table (contact_id, name)
select min(id), name
from contacts
group by name;
This is one way of ensuring only one row per name - you can substitute other functions for min (like, for eg max).
I'm not too sure why you would want to do this, though. No matter what, you will end up with some contacts that don't have a name linked to them...
ALTER TABLE `Contacts` ADD `name_id` INT( 12 ) NOT NULL
ALTER TABLE `Name` ADD `Name` VARCHAR( 200 ) NOT NULL
INSERT INTO Name (id, name) SELECT id, Name FROM Contacts
ALTER TABLE `Contacts` DROP `Name`
The problem is the name_id field, which is filles with "0" and should be have the same value as the id in the Contacts-Table. Here you can use the LOOP or ITERATE statement (if you using MySQL).