If you want to focus on the DEFAULT values, the built-in function GETDEFAULT can help, but as long as it requires to use numbers (you can't use a DB_ID(), a column or even a variable with the function) to escape this I made a procedure:
CREATE OR ALTER PROC PRC_GETDEFAULT(@TABLE_NAME VARCHAR(200)=NULL) AS BEGIN
SELECT
PK=ROW_NUMBER()OVER(ORDER BY COLUMN_ID)
,COLUMN_NAME = C.NAME
,DEFAULT_NAME = DC.NAME
,COLUMN_ID
,DEFAULT_OBJECT_ID = DC.OBJECT_ID
,DC.DEFINITION
,DB_ID=CONVERT(INT,DB_ID())
,DEFAULT_VALUE = CONVERT(SQL_VARIANT, NULL)
INTO #GET_DEFAULT
FROM SYS.DEFAULT_CONSTRAINTS DC
JOIN SYS.COLUMNS C ON DC.PARENT_OBJECT_ID = C.OBJECT_ID AND DC.PARENT_COLUMN_ID = C.COLUMN_ID
WHERE PARENT_OBJECT_ID = OBJECT_ID(@TABLE_NAME)
DECLARE @END INT = @@ROWCOUNT
DECLARE @I INT = 0
DECLARE @QORIGINAL VARCHAR(MAX) = '
UPDATE #GET_DEFAULT
SET DEFAULT_VALUE = GETDEFAULT(' + LTRIM(DB_ID()) + ','
DECLARE @QEXECUTE VARCHAR(MAX)
WHILE @I < @END BEGIN
SET @I += 1
SELECT @QEXECUTE = CONCAT(@QORIGINAL, DEFAULT_OBJECT_ID, ')
WHERE PK = ', @I)
FROM #GET_DEFAULT
WHERE PK = @I
EXEC(@QEXECUTE)
END
SELECT
*
FROM #GET_DEFAULT
END
This procedure only needs the table name and returns all the columns from the table that have default values and the active default values, example:
exec PRC_GETDEFAULT TB_EXAMPLE
--or
exec PRC_GETDEFAULT 'DBO.TB_EXAMPLE'