You can make this quite dynamic, where all you have to supply is the table name and the names of the candidate key columns. But you should also check to make sure if the column currently contains NULL values; otherwise, the ALTER will fail.
/* input */
DECLARE @table sysname = N'AS_tblTBCOV',
@cols nvarchar(max) = N'COV_SOC_NUM,COV_CLASS_NUM,COV_EFF_DATE';
DECLARE @qt sysname = QUOTENAME(@table);
DECLARE @obj int = OBJECT_ID(N'dbo.' + @qt);
DECLARE @keycols table(col sysname, dt nvarchar(128), nullable bit);
INSERT @keycols SELECT r.name, r.system_type_name, r.is_nullable
FROM STRING_SPLIT(@cols, N',') AS s
INNER JOIN sys.dm_exec_describe_first_result_set
(N'SELECT ' + @cols + ' FROM dbo.' + @qt, NULL, 0) AS r
ON r.name COLLATE DATABASE_DEFAULT = s.value;
DECLARE @sql nvarchar(max) = N'DECLARE @go bit = 1';
SELECT @sql += STRING_AGG(CONVERT(nvarchar(max),
N'IF EXISTS (SELECT 1 FROM dbo.' + @qt + '
WHERE ' + QUOTENAME(col) + ' IS NULL)
BEGIN
SET @go = 0;
RAISERROR(''' + col + ' contains NULLs'', 0, 1) WITH NOWAIT;
END'+ char(13) + char(10)), '')
FROM @keycols
WHERE nullable = 1;
SET @sql += N'IF @go = 1
BEGIN
';
SELECT @sql += STRING_AGG(CONVERT(nvarchar(max),
N' ALTER TABLE dbo.' + @qt
+ ' ALTER COLUMN ' + QUOTENAME(col) + ' ' + dt) + N' NOT NULL;',
char(13) + char(10) + char(9))
FROM @keycols
WHERE nullable = 1;
SET @sql += N'
END';
PRINT @sql;
--EXEC sys.sp_executesql @sql;
Seems quite messy but, in your case, it produces the much more tedious and repetitive:
DECLARE @go bit = 1
IF EXISTS (SELECT 1 FROM dbo.[AS_tblTBCOV]
WHERE [COV_CLASS_NUM] IS NULL)
BEGIN
SET @go = 0;
RAISERROR('COV_CLASS_NUM contains NULLs', 0, 1) WITH NOWAIT;
END
IF EXISTS (SELECT 1 FROM dbo.[AS_tblTBCOV]
WHERE [COV_EFF_DATE] IS NULL)
BEGIN
SET @go = 0;
RAISERROR('COV_EFF_DATE contains NULLs', 0, 1) WITH NOWAIT;
END
IF EXISTS (SELECT 1 FROM dbo.[AS_tblTBCOV]
WHERE [COV_SOC_NUM] IS NULL)
BEGIN
SET @go = 0;
RAISERROR('COV_SOC_NUM contains NULLs', 0, 1) WITH NOWAIT;
END
IF @go = 1
BEGIN
ALTER TABLE dbo.[AS_tblTBCOV] ALTER COLUMN [COV_CLASS_NUM] smallint NOT NULL;
ALTER TABLE dbo.[AS_tblTBCOV] ALTER COLUMN [COV_EFF_DATE] date NOT NULL;
ALTER TABLE dbo.[AS_tblTBCOV] ALTER COLUMN [COV_SOC_NUM] numeric(5,0) NOT NULL;
END
You write that constructor code once and it is reusable for any table / column combo.
(Keep in mind that changing a column's nullability can be a size-of-data operation and not simply a metadata change. Also that adding a primary key won't necessarily / broadly make queries more efficient - it depends on the queries and on whether the primary key is clustered. THat just happens to be the default.)