Files
Masterarbeit/QuellCode/CentronERP/docs/reference/database/script-rules.md
T
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

6.3 KiB

Centron Database Script Rules

These conventions must be followed for all database scripts in the Centron.BusinessLogic.Administration.Scripts.ScriptMethods.Scripts namespace. Scripts are used to update the SQL Server database by creating/altering tables, creating indexes, functions, triggers, and updating data when necessary.


1. Script Organization & Naming

  1. Placement

    • Place all scripts in the directory: src/backend/Centron.BL/Administration/Scripts/ScriptMethods/Scripts/
  2. Naming Convention

    • Name scripts using the pattern: ScriptMethod{NUMBER}.cs
    • The script number is managed in an external Excel file accessible through Teams
    • When creating a new script, use a placeholder for the number and update it with the next available number from the Excel file
  3. Class Structure

    • Each script class must inherit from BaseScriptMethod
    • The class name must match the filename
    internal class ScriptMethod11699 : BaseScriptMethod
    

2. Script Implementation

  1. Required Method

    • Override the GetSqlQueries() method from the base class
    • Return type should be IEnumerable<string>
    • Use yield return statements to return SQL statements
    public override IEnumerable<string> GetSqlQueries()
    {
        yield return ScriptHelpers.AddColumnIfNotExists("dbo", "TableName", "ColumnName", "datatype");
    }
    
  2. Using ScriptHelpers

    • Always use the ScriptHelpers class methods to generate SQL statements
    • This ensures consistency and safety in database operations
    • Common helper methods:
      • AddColumnIfNotExists
      • DropColumnIfExists
      • ChangeColumnTypeIfExists
      • AddTableIfNotExists
      • AddIndexIfNotExists
      • CreateSpecialObjectAlterIfExists
      • And many more in ScriptHelpers.cs

Script Helper Note

When using ScriptHelpers.AddTableIfNotExists() method in database scripts, the primary key column I3D is automatically created and does not need to be specified in the column list. The method internally handles the creation of:

  • The I3D [int] IDENTITY(1,1) NOT NULL column
  • The primary key constraint with appropriate clustering

Standard Audit Columns

  • Add CreatedByI3D, CreatedDate, IsDeleted, DeletedByI3D, and DeletedDate to new NHibernate-managed domain tables according to the standard entity conventions.
  • Add ChangedByI3D and ChangedDate only when rows are modified after creation.
  • Write-once/read-only history tables do not need Changed* columns. Examples: chat messages, tool call history, immutable communication logs.

3. Common Script Scenarios

  1. Adding or Changing Columns

    // Adding a column
    yield return ScriptHelpers.AddColumnIfNotExists("dbo", "TableName", "ColumnName", "datatype", nullable: true/false);
    
    // Changing a column type
    yield return ScriptHelpers.ChangeColumnTypeIfExists("dbo", "TableName", "ColumnName", "new_datatype");
    
  2. Creating Tables

    // Basic usage with dbo schema implied
    yield return ScriptHelpers.AddTableIfNotExists("TableName",
        ("Column1", "int", false, null),
        ("Column2", "nvarchar(100)", false, null),
        ("Column3", "datetime2(0)", true, null));
    
    // Explicit schema usage
    yield return ScriptHelpers.AddTableIfNotExists(
        schema: "dbo",
        table: "TableName",
        ("Column1", "int", false, null),
        ("Column2", "nvarchar(100)", false, null),
        ("IsActive", "bit", false, null));
    

    Parameter explanation:

    • Column format: (name, datatype, nullable, defaultValue)
    • For new NHibernate-managed tables, use null or an empty value for defaultValue
    • NHibernate writes all mapped columns on INSERT, so SQL defaults on new tables do not apply in normal application writes and only create unused SQL objects
    • Only consider SQL defaults when extending existing tables with new NOT NULL columns, where existing rows or non-NHibernate writers need a valid value
    • If defaultValue is empty, no default constraint will be created
    • The primary key column I3D is automatically created
    • Examples of justified default values:
      • For integers: "0", "1", etc.
      • For strings: "''" (empty string with single quotes)
      • For dates: "GETUTCDATE()"
      • For bits (boolean): "1" (true) or "0" (false)
  3. Creating Indexes

    yield return ScriptHelpers.AddIndexIfNotExists(
        table: "TableName", 
        indexName: "IX_TableName_Column1_Column2",
        columns: new List<(string column, OrderDirection? orderDirection)>
        {
            ("Column1", OrderDirection.ASC),
            ("Column2", OrderDirection.ASC),
        });
    
  4. Executing SQL Statements Directly

    yield return @"
    UPDATE TableName
    SET Column1 = 'value'
    WHERE Condition = 1;";
    
  5. Creating/Altering Views, Functions, Triggers

    yield return ScriptHelpers.CreateSpecialObjectAlterIfExists("ViewName", "VIEW", @"
    CREATE VIEW dbo.ViewName
    AS
    SELECT * FROM TableName
    WHERE Condition = 1;");
    

4. Best Practices

  1. Script Independence

    • Each script should be independent and idempotent
    • Use conditional checks like IF EXISTS and IF NOT EXISTS
  2. Script Safety

    • Always use ScriptHelpers methods when available
    • When direct SQL is needed, ensure proper schema references and SQL injection protection
  3. Performance Considerations

    • For large data operations, consider transaction management and batching
    • When modifying indexed columns, use AlterColumnTypeIndexSafe to preserve indexes
  4. Documentation

    • Add comments to clarify complex operations
    • For significant schema changes, document the purpose in a comment
  5. Testing

    • Test scripts in a development environment before applying to production
    • Verify the script achieves the intended changes without side effects

5. Examples

Refer to these existing scripts for common patterns:

  • ScriptMethod11699.cs - Adding columns and changing column types
  • ScriptMethod11698.cs - Executing direct SQL update statements
  • ScriptMethod11696.cs - Creating new tables
  • ScriptMethod11677.cs - Creating indexes
  • ScriptMethod11670.cs - Creating and altering views (same approach for triggers, functions)