An error occurred while the batch was being executed - sql-server

I am trying to add a foreign key to my database table, but I am getting this error:
An error occurred while the batch was being executed.
Possible data issues
The column [dbo].[Transactions].[Expenses_Id] on table [dbo].[Transactions] must be added, but the column has no default value and does not allow NULL values. If the table contains data, the ALTER script will not work. To avoid this issue you must either: add a default value to the column, mark it as allowing NULL values, or enable the generation of smart-defaults as a deployment option.
Warnings
The column [dbo].[Transactions].[Expenses_Id] on table [dbo].[Transactions] must be added, but the column has no default value and does not allow NULL values. If the table contains data, the ALTER script will not work. To avoid this issue you must either: add a default value to the column, mark it as allowing NULL values, or enable the generation of smart-defaults as a deployment option.
But my other table (the one I am referring to using the FK) is not empty, so there should not be any null exceptions.

You are attempting to add new column which does not allow NULLs. Since there are some rows already, what value should be in every row right after column creation? That is NULL or default if defined. Create it with allowed NULLs, update to real values, alter to disable NULLs.

Related

What does the FOR keyword do in this SQL Server ALTER TABLE clause?

I'm not sure what FOR is doing in this SQL Server snippet.
ALTER TABLE [dbo].[TableName]
ADD DEFAULT (NEXT VALUE FOR [dbo].[TableName_Seq]) FOR [TableName_Key]
When I try to google for FOR clause the only meaningful result I got was this, but I don't think it's relevant
FOR is a keyword of the NEXT VALUE FOR function. It is used to return the next value from the specified sequence object.
FOR is also a keyword of the DEFAULT constraint clause, specifying the target column name of the constraint.
In the context of the DDL in your question, the function result is the default value automatically assign the value when a value is not explicitly specified in INSERT statements.
BTW, it's a best practice to name constraints rather than relying on auto-generated names. This makes subsequent schema modifications easier.
FOR by itself has no specific meaning, it depends on context.
In this case, there are 2 usages of FOR:
NEXT VALUE FOR function, which is used to generate the next value from a sequence.
ALTER TABLE [table_name] ADD [table_constraint], where table_constraint is of the form DEFAULT constant_expression FOR column. So it's adding a default constraint for the TableName_Key column, and the value for that default constraint is coming from the TableName_Seq sequence.

Is NULL necessary?

Is NULL or NOT NULL necessary for Adding a column in SQL Server? (If you are going to run UPDATE statement after)
I tested without it locally, and it seems to work fine both in SQL and on the website; but I wanted to make sure before running release/production.
I looked up some other articles, including microsoft website. Some show it with, some without. SO articles say some benefits of NULL, like if you have information that may be added later. But assuming I am going to run UPDATE to add values after, will it matter?
I am guessing it does not matter from what I've tested and read.
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
UPDATE [dbo].[MyTable] SET NewColumn ='Math' WHERE ID = 1
UPDATE [dbo].[MyTable] SET NewColumn ='Science' WHERE ID = 2
You can skip it, and by default the column will be created as NULL. However it is more legible if you indicate it explicitly.
Keep in mind that if your table already has data, you CANNOT add the column as NOT NULL. For this, you should firstly add the column as NULL, then UPDATE the values with non-null valid data and then alter column to NOT NULL.
Edit: Assuming the default behavior of the sql server when adding columns.
You don't have to write it, when you skip it column will be created as 'NULL'.
Following statements are equal:
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150) NULL;
If you want to add a column and DB engine should guarantee you that this new column will be always populated you can add a NOT NULL column with a default value.
Other option will be to change the column to NOT NULL after the update.
I'd make sure you have something declarative. And if you are setting as "not null," be sure you have a default value or use can suffer LOTS of data loss if data previously exists. It makes me nervous because this an ALTER vs a CREATE.

SQL Server Computed Column that doesn't affect existing data

is that possible to do a computed column without affecting existing data?
I have a unique index column named
"BookingNo"
For newly insert Column I want it to be following this format
(format([CreationTime],'yyMMddHHmmssff'))
I tried used Computed Column but it modified all my existing data.
my existing BookingNo format was
201800123
Is there anyway to generate via database? Or we have insert via code?
You could just add a default constraint:
ALTER TABLE TableName
ADD CONSTRAINT DF_BookingNo DEFAULT(format(SYSDATETIME(),'yyMMddHHmmssff'))
FOR BookingNo
This way you will get the value only for newly created rows.
Please note that if this column has a unique constraint on it some inserts might fail if they are executed at the same time.

EF - pass null value to SQL column so default value gets inserted

SQL Server table T2 has 2 columns:
Id INT NOT NULL
CreateDate DateTime NOT NULL, default = (getdate())
This statement inserts the CreateDate value correctly because it uses (getdate()) as default.
Insert T2 (Id)
Values (1)
So far so good. The problem is when I use Entity Framework to insert a row and still wish to use the default (getdate()) value.
Because the CreateDate is defined as NOT NULL, I cannot leave it blank or leave out of the Insert statement when using EF. But I want SQL to generate the timestamp on the server/database side.
Is there a way to handle this?
Thanks to squillman's reference to another SO post, I was able to find the answer.
Go to EDMX diagram, and you can set the StoreGeneratedPattern property to achieve what I am trying to do.
There are three Database Generated Options
Computed : The database generates a value when a row is inserted or updated.
Identity : The database generates a value when a row is inserted.
None : The database does not generate values.
EDIT: Although the picture shows Identity, I had to change it to Computed. The reason is that Identity option only works if the row is Inserted only. If the row is ever updated (other columns updated), then it caused an error. The Computed option seems to work fine with Insert (runs the default script) and Updates (to other columns, default script does not run again).

DB2 override auto generated key when inserting

I want to insert an item to a table in the database. The table has a key that is auto generated. Is it possible to override the auto generated key, (force a value). If so how?
I'm going to assume you are talking about identity columns and not sequences.
In DB2's CREATE TABLE syntax, have a look at the "generated-column-spec" in the syntax diagram as it relates to identity columns. There are two ways to specify how the identity value will be generated:
GENERATED ALWAYS: this option will always generate and identity value, and you cannot specify a value for the identity column in an insert statement
GENERATED BY DEFAULT: this option will generate an identity value if no value for the column is specified in the insert statement. If you provide a value for the column in the insert statement, db2 will not generate an identity value for it.
If the table you are trying to insert into used the ALWAYS option when the table is created, then you cannot override it. You'll need to drop and recreate the table or use the ALTER TABLE statement to redefine the column to generate the identity value by default only.
If you're trying to LOAD data into a table that has an identity column which is GENERATED ALWAYS then you can do this:
db2 load from tab43.ixf of ixf modified by identityoverride into tablename

Resources