Utility Procedures
Technical Details

Technical details for Utility Procedures used by dbOmnibus.

| Procedure List |

These utility procedures are used internally by dbOmnibus and are not intended to be executed manually.


sp_UpdateConfig

Not documented at this time.

@@@---@@@

This SQL script defines and creates the stored procedure [Util].[sp_UpdateConfig]. This utility procedure is designed to either insert a new configuration record or update an existing one in the [Lookup].[Config] table. It provides granular control over which fields are updated based on the provided parameters.

Script Breakdown
1. Metadata, Versioning, and Idempotent Placeholder Creation
The script begins with the standard pattern for deploying procedures within this framework:

Metadata Declaration:

SQL

DECLARE @Name [varchar](128), @Description [varchar](128), @Version [int], @Type [varchar](5);
SET @Version=240821;
SET @Type='P';
SET @Name='sp_UpdateConfig';
SET @Description='Update or Insert records in the [Config] table';
These lines set the metadata for the sp_UpdateConfig procedure, including its version (240821).

EXEC [Deploy].[sp_UpdateEntityVer] @Type=@Type, @Name=@Name, @Description=@Description, @Version=@Version;: This call records the procedure's version in the temporary #EntityVers table, which will later be persisted.

EXEC [Deploy].[sp_CreateEmptyObject] @Type=@Type, @Name=@Name, @Schema='Util';: This ensures that a placeholder for sp_UpdateConfig exists in the [Util] schema. This is a robust way to ensure the subsequent ALTER PROCEDURE statement will succeed, whether the procedure is being created for the first time or updated.

GO: Separates the setup commands from the procedure definition.

2. [Util].[sp_UpdateConfig] Stored Procedure Definition
This is the main logic for updating or inserting configuration records:

Parameters:
@Id [int]: Mandatory. The ID of the configuration record. This procedure explicitly uses IDENTITY_INSERT to allow the caller to specify the ID for insertion or to identify the record for update.

@Key [int]=0: Optional. The integer key of the configuration item. Defaults to 0. If 0, it won't be updated in an existing record.

@Key_Desc [varchar](255)='': Optional. The description of the configuration key. Defaults to an empty string. If empty, it won't be updated.

@Value [varchar](MAX)='NONE': Optional. The actual configuration value. Defaults to 'NONE'. If 'NONE', it won't be updated.

@AddOnly [bit]=0: Optional. If 1, the procedure will only attempt to INSERT a new record. If a record with @Id already exists, it will RETURN without updating. Defaults to 0.

@Advanced [bit]=0: Optional. A flag to designate the configuration item as "advanced." Used only during INSERT.

Internal Variables:
@SqlCode [varchar](1024): Used to build the dynamic SQL UPDATE statement. Note that varchar(1024) might be too small if @Value (which is varchar(MAX)) were to be included dynamically in its entirety. However, since @Value is concatenated as a literal, it means @Value itself cannot contain single quotes unless properly escaped, and the total length of @SqlCode could exceed 1024 characters. nvarchar(MAX) is generally safer for dynamic SQL.

@NSqlCode [nvarchar](1024): Used to cast @SqlCode to nvarchar before execution. This is good practice for EXEC. The same length limitation applies.

@AddComma [bit]: A flag used to manage comma placement when building the dynamic UPDATE statement.

Logic:
SET NOCOUNT ON;: Suppresses row count messages.

SET IDENTITY_INSERT [Lookup].[Config] ON;: This crucial statement allows explicit values to be inserted into the ID identity column. It must be ON before inserting records where the ID is provided and must be OFF afterward.

Check for Existing Record:

IF NOT EXISTS (SELECT * FROM [Lookup].[Config] WHERE ID = @Id): Checks if a record with the given @Id exists.

INSERT Block: If no record exists, it inserts a new row into [Lookup].[Config] using all provided parameters (@Id, @Key, @Key_Desc, @Value, @Advanced).

ELSE (Update Block): If a record does exist:

IF @AddOnly = 1 RETURN;: If @AddOnly is 1, the procedure immediately exits without performing any update. This enforces an "insert-only" behavior for existing IDs.

Dynamic UPDATE Statement Construction:

Starts building the UPDATE statement: SET @SqlCode = ' UPDATE [Lookup].[Config] SET '.

Conditional Field Updates: It conditionally adds [Key], [Key_Desc], and [Value] to the SET clause based on their default "empty" or "not provided" values (0, '', 'NONE').

@AddComma logic is used to correctly place commas between updated fields.

Concatenation Vulnerability: The direct concatenation of @Key_Desc and @Value into the dynamic SQL SET @SqlCode = @SqlCode + ' [Key_Desc]=''' + @Key_Desc + '''' and SET @SqlCode = @SqlCode + ' [Value]=''' + @Value + '''' is vulnerable to SQL Injection if @Key_Desc or @Value parameters can contain single quotes that are not properly escaped by the caller. Using QUOTENAME() for string values or sp_executesql with proper parameterization would be much safer.

Commented Email Validation: A commented-out block shows a placeholder for future email validation, indicating a potential enhancement.

SET @SqlCode = @SqlCode + ' WHERE [ID]=' + CAST(@Id AS [varchar](5));: Completes the UPDATE statement with the WHERE clause.

Execution:

SET @NSqlCode = @SqlCode;

EXEC (@NSqlCode);: Executes the dynamically constructed UPDATE statement.

SET IDENTITY_INSERT [Lookup].[Config] OFF;: This line is essential to turn off IDENTITY_INSERT after the operation, returning the table to its normal identity behavior. This must always be done to avoid affecting other operations on the table.

Purpose and Usage
[Util].[sp_UpdateConfig] is a core CRUD (Create, Read, Update, Delete) utility for managing application configuration within the database.

Centralized Configuration Management: Provides a controlled way to add or modify configuration settings.

Flexible Updates: Allows updating only specific fields of a configuration record by ignoring default parameter values.

Idempotent Operations: The IF NOT EXISTS for insert and IF @AddOnly = 1 for update help make the procedure robust to repeated calls.

Data Integrity: Requires explicit ID values and uses IDENTITY_INSERT, which demands careful handling by the caller.

Example Usage (from script comments):

Insert a new config item (if ID 1 does not exist):

SQL

EXEC [Util].[sp_UpdateConfig] @Id = 1, @Key = 100, @Key_Desc = 'Application Name', @Value = 'My Awesome App', @Advanced = 0;
Update an existing config item (if ID 1 exists, and @AddOnly is not 1):

SQL

EXEC [Util].[sp_UpdateConfig] @Id = 1, @Value = 'Updated App Name';
Attempt to add, but do not update if exists:

SQL

EXEC [Util].[sp_UpdateConfig] @Id = 1, @Key = 100, @Key_Desc = 'Application Name', @Value = 'My App', @AddOnly = 1; -- If ID 1 exists, this will do nothing.
Potential Enhancements/Considerations:

SQL Injection Vulnerability: The direct string concatenation for @Key_Desc and @Value is a security risk. This should be refactored to use sp_executesql with parameterized queries.

varchar(MAX) in dynamic SQL: If @Value were truly MAX length and concatenated, it could easily exceed the varchar(1024) limit of @SqlCode and @NSqlCode. This reinforces the need for nvarchar(MAX) for the dynamic SQL variables and parameterization.

Data Type Mismatch: @Key is an int, but @Key_Desc and @Value are varchar. This is fine, but the [Lookup].[Config] table definition used nvarchar for Key_Desc and Value. Using nvarchar for @Key_Desc and @Value parameters in the procedure itself would prevent implicit conversions and data loss if Unicode characters are passed.

No @Advanced update: The @Advanced parameter is only used during INSERT, not during UPDATE. This might be intentional, but worth noting.

 


Page Last Updated: 21 September 2025