How not to store a value in a column? - sql

I've got me this nice table.
create table Records (
Id uniqueidentifier primary key,
Occasion datetime not null,
Information varchar(999) default ' '
)
When I execute the first line line below, I get an error. When I execute the second, I see NULL in the cell. How should I insert stuff into the table so that the default white space kicks in?
insert into Records values (newid(), convert(varchar(21), getdate(), 121))
insert into Records values (newid(), convert(varchar(21), getdate(), 121), null)
The error message is the defaulty one but I'll put it in here anyway, in case someone asks.
Column name or number of supplied values does not match table definition.

By using the DEFAULT keyword:
INSERT INTO Records VALUES (newid(), CONVERT(varchar(21), getdate(), 121), DEFAULT)
Or, better, by specifying the exact columns with the INSERT statement
INSERT INTO Records (Id, Occasion)
VALUES (newid(), CONVERT(varchar(21), getdate(), 121))
Or:
INSERT INTO Records (Id, Occasion, Information)
VALUES (newid(), CONVERT(varchar(21), getdate(), 121), DEFAULT)
Why is it better?
Because you shouldn't rely on the order of columns in your table.
Because you shouldn't rely on the fact that the table will never have any new or removed columns (which is when your query will break again).
Also interesting: SQL Column definition : default value and not null redundant?

insert into Records (
Id
Occasion
)
values (newid(), convert(varchar(21), getdate()), 121))
Try this.
when you don't specify column names in insert query, sql-server expects values for all the columns. that is why your first query is throwing error as you have supplied value for two columns only, whereas your second query is running correctly

Try this:
insert into Records values (newid(), convert(varchar(21), getdate()), 121)
You have to close the ( of convert.

Related

Inserting missing date into non nullable Datetime field

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.

How can i use default value on postgres when query include null value

I use Postgres and I've integration app which write data to database. My column should not be null but my app send null value. I tried to set default value but query override this rule with null value. How can i handle this change without code.
My Column configuration looks like this.
If you won't or can't change the query in code, you have to use trigger
If you can change code structure and query:
If the column has a default value, then no need to send NULL value to query
-- Before change
insert into your_table (id, name, default_col) values
(1, 'name', null);
-- After change (remove null data)
insert into your_table (id, name) values
(1, 'name');
Or send default value in insert query
-- Before change
insert into your_table (id, name, default_col) values
(1, 'name', null);
-- After change (Use default keyboard)
insert into your_table (id, name, default_col) values
(1, 'name', default);

Leveraging CHECKSUM in MERGE but unable to get all rows to merge

I am having trouble getting MERGE statements to work properly, and I have recently started to try to use checksums.
In the toy example below, I cannot get this row to insert (1, 'ANDREW', 334.3) that is sitting in the staging table.
DROP TABLE TEMP1
DROP TABLE TEMP1_STAGE
-- create table
CREATE TABLE TEMP1
(
[ID] INT,
[NAME] VARCHAR(55),
[SALARY] FLOAT,
[SCD] INT
)
-- create stage
CREATE TABLE TEMP1_STAGE
(
[ID] INT,
[NAME] VARCHAR(55),
[SALARY] FLOAT,
[SCD] INT
)
-- insert vals into stage
INSERT INTO TEMP1_STAGE (ID, NAME, SALARY)
VALUES
(1, 'ANDREW', 333.3),
(2, 'JOHN', 555.3),
(3, 'SARAH', 444.3)
-- insert stage table into main table
INSERT INTO TEMP1
SELECT *
FROM TEMP1_STAGE;
-- clean up stage table
TRUNCATE TABLE TEMP1_STAGE;
-- put some new values in the stage table
INSERT INTO TEMP1_STAGE (ID, NAME, SALARY)
VALUES
(1, 'ANDREW', 334.3),
(4, 'CARL', NULL)
-- CHECKSUMS
update TEMP1_STAGE
set SCD = binary_checksum(ID, NAME, SALARY);
update TEMP1
set SCD = binary_checksum(ID, NAME, SALARY);
-- run merge
MERGE TEMP1 AS TARGET
USING TEMP1_STAGE AS SOURCE
-- match
ON (SOURCE.[ID] = TARGET.[ID])
WHEN NOT MATCHED BY TARGET
THEN INSERT (
[ID], [NAME], [SALARY], [SCD]) VALUES (
SOURCE.[ID], SOURCE.[NAME], SOURCE.[SALARY], SOURCE.[SCD]);
-- the value: (1, 'ANDREW', 334.3) is not merged in
SELECT * FROM TEMP1;
How can I use the checksum to my advantage in the MERGE?
Your issue is that the NOT MATCHED condition is only considering the ID values specified in the ON condition.
If you want duplicate, but distinct records, include SCD to the ON condition.
If (more likely) your intent is that record ID = 1 be updated with the new SALARY, you will need to add a WHEN MATCHED AND SOURCE.SCD <> TARGET.SCD THEN UPDATE ... clause.
That said, the 32-bit int value returned by the `binary_checksum()' function is not sufficiently distinct to avoid collisions and unwanted missed updates. Take a look at HASHBYTES instead. See Binary_Checksum Vs HashBytes function.
Even that may not yield your intended performance gain. Assuming that you have to calculate the hash for all records in the staging table for each update cycle, you may find that it is simpler to just compare each potentially different field before the update. Something like:
WHEN MATCHED AND (SOURCE.NAME <> TARGET.NAME OR SOURCE.SALARY <> TARGET.SALARY)
THEN UPDATE ...
Even then, you need to be careful of potential NULL values and COLLATION. Both NULL <> 50000.00 and 'Andrew' <> 'ANDREW' may not give you the results you expect. It might be easiest and most reliable to just code WHEN MATCHED THEN UPDATE ....
Lastly, I suggest using DECIMAL instead of FLOAT for Salary.

Missing Semicolon at the end of sql statement Access

I am trying to execute the following code. However, I continue to recieve the following 'Missing semicolon (;) at the end of SQL statement error in Microsoft Access.
The first query creates the table with the columns defined.
create table test
(
ProcessID int,
Name varchar(10),
Address varchar(10),
RandomData varchar(10)
);
The second query is causing the missing semicolon error.
INSERT into test
VALUES (123 , 'TestName', 'TestAdd', 'qwrj3ri'),
(456 , 'TestName2', 'TestAdd', 'qwerty'),
(789 , 'TestName', 'TestAdd', 'qwrj3ri'),
(1234, 'Testing123', 'tester', 'asdfghjk');
Code with amendments per above comments to make it Access friendly & remove typos:
INSERT INTO test ( ProcessID, Name, Address, RandomData)
VALUES (123 , 'TestName', 'TestAdd', 'qwrj3ri');
INSERT INTO test ( ProcessID, Name, Address, RandomData)
VALUES (456 , 'TestName2', 'TestAdd', 'qwerty');
INSERT INTO test ( ProcessID, Name, Address, RandomData)
VALUES (789 , 'TestName', 'TestAdd', 'qwrj3ri');
INSERT INTO test ( ProcessID, Name, Address, RandomData)
VALUES (1234, 'Testing123', 'tester', 'asdfghjk');
Useful reference: https://msdn.microsoft.com/en-us/library/bb243852(v=office.12).aspx
Specific comments:
#Damien_The_Unbeliever:
I don't think access supports multiple rows in the values.
Amended to include an insert into per row instead of a value set per row (values (...), (...)).
#Thomas Tschernich:
our missing single quote next to the end of your insert
Changed 'tester', sdfg') to 'tester', 'sdfg');
#JohnLBevan:
superfluous character on end of first set of values
Changed 'qwrj3ri'), T to 'qwrj3ri'),
You can insert multiple rows in one insert statement in SQL server,but in MS ACCESS its not possible as above listed.
More techniques on multiple inserts in access are described
beautifully here

MS SQL INSERT INTO trouble

I need to insert new record in table.
The first column name ob_no is int, not null. So I need generate number which is maximum ob_no at the moment +1. How can I do it? Something Like (max(ob_no) + 1) but it doesn't work in SQL 2005. Thanks for any ideas.
INSERT INTO et_thanks_2014 (ob_no, c_name)
VALUES (???, 'Some Text')
You should use identities if you don't need values without lag:
INSERT INTO et_thanks_2014 (ob_no, c_name)
SELECT MAX(ob_no) + 1, 'Some Text'
FROM et_thanks_2014