Inserting missing date into non nullable Datetime field - sql

Here we have an existing database and I'm building a new system with a new database.
There I need to transfer some data from the old database table to the new database table.
I wrote this query in the SQL
INSERT INTO [Mondo-UAT].[dbo].[Countries] (
[Country_Name]
,[Country_Code]
,[Note]
)
SELECT [Code1]
,[Code3]
,[Name]
FROM [MondoErp-UAT].[dbo].[Nations]
The issue is in the [Mondo-UAT].[dbo].[Countries] table has other columns like Note is a string and Status is a bool CreateBy is int CreateDate is DateTime . So when I run the query it returns with an error
Msg 515, Level 16, State 2, Line 8 Cannot insert the value NULL into column 'CreatedDate', table 'Mondo-UAT.dbo.Countries'; column does not allow nulls. INSERT fails. The statement has been terminated
So I wanna know how to insert data for the CreateDate,CreateBy ,Notes from the above script I wrote.

If the target table has non-nullable columns without defaults, you have to specify values for those fields when inserting data.
The easiest solution would be to modify the target table to add DEFAULT values for those fields, eg SYSDATETIME() for Created, SYSTEM_USER for CreatedBy and '' for Notes. For Status you'll have to decide what a good default status is. 0 may or may not be meaningful.
Otherwise, these values will have to be specified in the query:
INSERT INTO [Mondo-UAT].[dbo].[Countries] (
[Country_Name]
,[Country_Code]
,[Note]
, Created
, CreatedBy
, Status
)
SELECT [Code1]
,[Code3]
,[Name]
, SYSDATETIME()
, SYSTEM_USER
, 0
FROM [MondoErp-UAT].[dbo].[Nations]
SYSTEM_USER returns the login name of the current user, whether it's a Windows or SQL Server login. This makes it a good default for user columns.
SYSDATETIME returns the current time as a DATETIME2(7) value. If Created is a DATETIMEOFFSET, SYSDATETIMEOFFSET should be used.

You can set Default Value for CreateDate,CreateBy,Notes columns in the [Mondo-UAT].[dbo].[Countries] table if they are not null columns. So, When you insert data into the table and do not insert a value for these columns, the default value will be inserted.

Related

Select row just inserted without using IDENTITY column in SQL Server 2012

I have a bigint PK column which is NOT an identity column, because I create the number in a function using different numbers. Anyway, I am trying to save this bigint number in a parameter #InvID, then use this parameter later in the procedure.
ScopeIdentity() is not working for me, it saved Null to #InvID, I think because the column is not an identity column. Is there anyway to select the record that was just inserted by the procedure without adding an extra ID column to the table?
It would save me a lot of effort and work if there is a direct way to select this record and not adding an id column.
insert into Lab_Invoice(iID, iDate, iTotal, iIsPaid, iSource, iCreator, iShiftID, iBalanceAfter, iFileNo, iType)
values (dbo.Get_RI_ID('True'), GETDATE(),
(select FilePrice from LabSettings), 'False', #source, #user, #shiftID, #b, #fid, 'Open File Invoice');
set #invID = CAST(scope_identity() AS bigint);
P.S. dbo.Get_RI_ID('True') a function returns a bigint.
Why don't you use?
set #invId=dbo.Get_RI_ID('True');
insert into Lab_Invoice(iID,iDate,iTotal,iIsPaid,iSource,iCreator,iShiftID,iBalanceAfter,iFileNo,iType)
values(#invId,GETDATE(),(select FilePrice from LabSettings),'False',#source,#user,#shiftID,#b,#fid,'Open File Invoice');
You already know that big id value. Get it before your insert statement then use it later.
one way to get inserted statement value..it is not clear which value you are trying to get,so created some example with dummy data
create table #test
(
id int
)
declare #id table
(
id int
)
insert into #test
output inserted.id into #id
select 1
select #invID=id from #id

Confusion about Stored Procedure

I have written a stored procedure for inserting data into my table. These are my table's columns with their datatype:
Ad nvarchar(150),
Yazar nvarchar(150),
SayfaSayisi smallint,
KategoriId int
Gmc datetime,
HostName nvarchar(150)
The problem is that Gmc and HostName have their own default values. So I can't use these two in the stored procedure.
Gmc ---> GetDate() (to get insert date)
HostName --> Host_Name( )
So when I execute the query I am getting this error.
There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement
This is the query
Create proc Kitap_Insert
#Ad nvarchar(150),
#Yazar nvarchar(150),
#SayfaSayisi smallint,
#KategoriId int
Gmc datetime,
HostName nvarchar(150)
as
Insert into Kitap(Id, Ad, Yazar, SayfaSayisi, KategoriId)
values(#Ad, #Yazar, #SayfaSayisi, #KategoriId)
What is the proper way of doing this?
You need remove ID from insert list
Insert into Kitap(Ad,Yazar,SayfaSayisi,KategoriId)
values(#Ad,#Yazar,#SayfaSayisi,#KategoriId)
or add a value for it as below
Insert into Kitap(Id,Ad,Yazar,SayfaSayisi,KategoriId)
values(#ID, #Ad,#Yazar,#SayfaSayisi,#KategoriId)
Instead of :
Insert into Kitap(Id,Ad,Yazar,SayfaSayisi,KategoriId)
values(#Ad,#Yazar,#SayfaSayisi,#KategoriId)
Use:
INSERT INTO Kitap(Ad,Yazar,SayfaSayisi,KategoriId)
VALUES (#Ad,#Yazar,#SayfaSayisi,#KategoriId)
You are asking SQL engine that you will provide id (an additional field) as well (field that doesn't exist in the table or is an auto increment field) and you are not providing the value for the same and hence your error here are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement
So remove additional Id from your insert query.
The error you are getting because you tried to insert value into more column names than specified in Values Clause.
If you have ID column as Auto-increment field in table so you dont have to include that ID column in so your insert query will be like this:-
Insert into Kitap
(Ad,Yazar,SayfaSayisi,KategoriId)
values
(#Ad,#Yazar,#SayfaSayisi,#KategoriId)
If you don't have ID column as Auto-increment field in table so you provide value to that id column also in Value Clause so your insert query will be like this:-
NOTE:-
You have to calculate and Set Value to #Id variable before using it in Insert Query
Declare #Id as INT
SET #ID = ---- set here with some value which will become Primary key(I think)
Insert into Kitap
(Id,Ad,Yazar,SayfaSayisi,KategoriId)
values
(#Id, #Ad,#Yazar,#SayfaSayisi,#KategoriId)

What means DEFAULT VALUES specification in an insert query?

I am pretty new in Microsoft SQL Server and I am not so into DB in general.
I have the following doubt about an insert query that begin in this way:
insert into MyTable DEFAULT VALUES
What exactly mean the DEFAULT VALUES specification?
Tnx
Andrea
Reading the fine manual yields:
DEFAULT VALUES
Forces the new row to contain the default values defined for each column.
Well it uses the default values specified in your table.
So for example if you have a column CreationDate datetime default(getdate()) it will use it.
If each of the required columns in MyTable has specified DEFAULT VALUE then this statement insert such a row.
For example you could have column Date with default 01/01/2014 and position with DEFAULT 'Developer' and this statement would insert such a record.
You can read more here: http://msdn.microsoft.com/en-us/library/aa933206%28SQL.80%29.aspx
You can watch default specifications in work by checking that code:
DECLARE #tmp as table
(
id int null,
num int null default(777),
txt varchar(10) null default('abc'),
date datetime null
)
insert into #tmp DEFAULT VALUES
select * from #tmp
Output is
id num txt date
NULL 777 abc NULL

SQL Server 2012 sequence

I create a table and sequence in order to replace identity in the table I use SQL Server 2012 Express but I get this error while I tried to insert data to the table
Msg 11719, Level 15, State 1, Line 2
NEXT VALUE FOR function is not allowed in check constraints, default objects, computed columns,
views, user-defined functions, user-defined aggregates, user-defined
table types, sub-queries, common table expressions, or derived
tables.
T-SQL code:
insert into Job_Update_Log(log_id, update_reason, jobid)
values((select next value for Job_Log_Update_SEQ),'grammer fixing',39);
This is my table:
create table Job_Update_Log
(
log_id int primary key ,
update_reason nvarchar(100) ,
update_date date default getdate(),
jobid bigint not null,
foreign key(jobid) references jobslist(jobid)
);
and this is my sequence:
CREATE SEQUENCE [dbo].[Job_Log_Update_SEQ]
AS [int]
START WITH 1
INCREMENT BY 1
NO CACHE
GO
Just get rid of the subselect in the VALUES section, like this:
insert into Job_Update_Log(log_id,update_reason,jobid)
values (next value for Job_Log_Update_SEQ,'grammer fixing',39);
Reference: http://msdn.microsoft.com/en-us/library/hh272694%28v=vs.103%29.aspx
Your insert syntax appears to be wrong. You are attempting to use a SELECT statement inside of the VALUES section of your query. If you want to use SELECT then you will use:
insert into Job_Update_Log(log_id,update_reason,jobid)
select next value for Job_Log_Update_SEQ,'grammer fixing',39;
See SQL Fiddle with Demo
I changed the syntax from INSERT INTO VALUES to INSERT INTO ... SELECT. I used this because you are selecting the next value of the sequence.
However, if you want to use the INSERT INTO.. VALUES, you will have to remove the SELECT from the query:
insert into Job_Update_Log(log_id,update_reason,jobid)
values(next value for Job_Log_Update_SEQ,'grammer fixing',39);
See SQL Fiddle with Demo
Both of these will INSERT the record into the table.
Try this one:
–With a table
create sequence idsequence
start with 1 increment by 3
create table Products_ext
(
id int,
Name varchar(50)
);
INSERT dbo.Products_ext (Id, Name)
VALUES (NEXT VALUE FOR dbo.idsequence, ‘ProductItem’);
select * from Products_ext;
/* If you run the above statement two types, you will get the following:-
1 ProductItem
4 ProductItem
*/
drop table Products_ext;
drop sequence idsequence;
------------------------------

Adding max(value)+1 in new row, can this be a problem?

In a SQL Server table I have the following 2 columns:
RowId: primary key, numaric, identity column and auto insert.
MailId: Non key, numaric, non identity and non auto insert.
Mail Id can be duplicate. In case of new MailId I will check max(MailId)+1 and insert it in new row and in case of duplication value will be coming as parameter.
Logic looks fine but here is an issue, I was just considering (yet chacnes of accurance are ver low) In the same time there can be two different new MailId requests. Can this casue logical error ? For example when code checked max(MailId)+1 was 101 and I stored it in a variable but may be before next insert statment executs a new record inserted in table. Now max(MailId)+1 in table will be 102 but value in variable will be 101 ?
Any suggestion please I want to control this error chances as well.
EDIT
(I am not using identity(1,1) because I also have to pass custom values in it)
Why would you use a custom-rolled Identity field when there is such a great one already in SQL Server?
Just use INT Identity (1,1) for your ID field and it will automatically increment each time a row is inserted. It also handles concurrency much better than pretty much anything you could implement manually.
EDIT:
Sample of a manual ID value:
SET IDENTITY_INSERT MyTable ON
INSERT INTO MyTable (IdField, Col1, Col2, Col3,...)
VALUES
(1234, 'Col1', 'Col2', 'Col3',...)
SET IDENTITY_INSERT MyTable OFF
You need to include an explicit field list for the INSERT.
Use OUTPUT on your insert to be sure that you have the right value. If you insert and then select MAX, it is possible that someone could "sneak" in and end up with duplication. That is, you insert MAX + 1, at the same time someone else inserts MAX + 1 then you select MAX and they select MAX, you both have the same value. Whereas if you INSERT and use OUTPUT, you'll be sure that you're unique. This is rarely a problem, but if you have a lot of activity, it can happen (speaking from experience).
EDIT
USE AdventureWorks2008R2;
GO
DECLARE #MyTableVar table(
EmpID int NOT NULL,
OldVacationHours int,
NewVacationHours int,
ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
ModifiedDate = GETDATE()
OUTPUT inserted.BusinessEntityID,
deleted.VacationHours,
inserted.VacationHours,
inserted.ModifiedDate
INTO #MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM #MyTableVar;
GO
--Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO