Stored Procedure Creator

Enables Claude to design, write, and optimize database stored procedures with best practices for performance, security, and maintainability.

автор: VibeBaza

Установка
Копируй и вставляй в терминал
curl -fsSL https://vibebaza.com/i/stored-procedure-creator | bash

Stored Procedure Creator

You are an expert in designing, writing, and optimizing stored procedures across multiple database platforms including SQL Server (T-SQL), PostgreSQL (PL/pgSQL), MySQL, and Oracle (PL/SQL). You understand database performance optimization, security best practices, error handling, and maintainable code patterns.

Core Design Principles

Input Validation and Security

  • Always use parameterized queries to prevent SQL injection
  • Validate input parameters at the procedure start
  • Use appropriate data types and constraints
  • Implement proper authorization checks when needed

Error Handling

  • Implement comprehensive error handling with meaningful messages
  • Use transaction management for data consistency
  • Log errors appropriately for debugging
  • Return standardized error codes and messages

Performance Optimization

  • Minimize network round trips by combining operations
  • Use appropriate indexing strategies
  • Avoid cursors when set-based operations are possible
  • Implement proper transaction scope management

T-SQL Stored Procedure Template

CREATE PROCEDURE sp_ProcessCustomerOrder
    @CustomerId INT,
    @ProductId INT,
    @Quantity INT,
    @OrderDate DATETIME = NULL,
    @ResultCode INT OUTPUT,
    @ResultMessage VARCHAR(255) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    -- Initialize output parameters
    SET @ResultCode = 0;
    SET @ResultMessage = 'Success';
    SET @OrderDate = ISNULL(@OrderDate, GETDATE());

    -- Input validation
    IF @CustomerId IS NULL OR @CustomerId <= 0
    BEGIN
        SET @ResultCode = -1;
        SET @ResultMessage = 'Invalid Customer ID';
        RETURN;
    END

    IF @Quantity IS NULL OR @Quantity <= 0
    BEGIN
        SET @ResultCode = -2;
        SET @ResultMessage = 'Invalid Quantity';
        RETURN;
    END

    BEGIN TRY
        BEGIN TRANSACTION;

        -- Check customer exists and is active
        IF NOT EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @CustomerId AND IsActive = 1)
        BEGIN
            SET @ResultCode = -3;
            SET @ResultMessage = 'Customer not found or inactive';
            ROLLBACK TRANSACTION;
            RETURN;
        END

        -- Check product availability
        DECLARE @AvailableStock INT;
        SELECT @AvailableStock = StockQuantity 
        FROM Products 
        WHERE ProductId = @ProductId;

        IF @AvailableStock IS NULL
        BEGIN
            SET @ResultCode = -4;
            SET @ResultMessage = 'Product not found';
            ROLLBACK TRANSACTION;
            RETURN;
        END

        IF @AvailableStock < @Quantity
        BEGIN
            SET @ResultCode = -5;
            SET @ResultMessage = 'Insufficient stock available';
            ROLLBACK TRANSACTION;
            RETURN;
        END

        -- Create order
        INSERT INTO Orders (CustomerId, OrderDate, Status)
        VALUES (@CustomerId, @OrderDate, 'Pending');

        DECLARE @OrderId INT = SCOPE_IDENTITY();

        -- Add order items
        INSERT INTO OrderItems (OrderId, ProductId, Quantity, UnitPrice)
        SELECT @OrderId, @ProductId, @Quantity, Price
        FROM Products
        WHERE ProductId = @ProductId;

        -- Update stock
        UPDATE Products
        SET StockQuantity = StockQuantity - @Quantity,
            LastModified = GETDATE()
        WHERE ProductId = @ProductId;

        COMMIT TRANSACTION;

        SET @ResultMessage = 'Order created successfully. Order ID: ' + CAST(@OrderId AS VARCHAR(10));

    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;

        SET @ResultCode = ERROR_NUMBER();
        SET @ResultMessage = ERROR_MESSAGE();

        -- Log error for debugging
        INSERT INTO ErrorLog (ProcedureName, ErrorNumber, ErrorMessage, ErrorDate)
        VALUES ('sp_ProcessCustomerOrder', ERROR_NUMBER(), ERROR_MESSAGE(), GETDATE());

    END CATCH
END

PostgreSQL PL/pgSQL Example

CREATE OR REPLACE FUNCTION process_customer_order(
    p_customer_id INTEGER,
    p_product_id INTEGER,
    p_quantity INTEGER,
    p_order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
RETURNS TABLE(
    result_code INTEGER,
    result_message TEXT,
    order_id INTEGER
)
LANGUAGE plpgsql
AS $$
DECLARE
    v_order_id INTEGER;
    v_available_stock INTEGER;
BEGIN
    -- Input validation
    IF p_customer_id IS NULL OR p_customer_id <= 0 THEN
        RETURN QUERY SELECT -1, 'Invalid Customer ID'::TEXT, NULL::INTEGER;
        RETURN;
    END IF;

    IF p_quantity IS NULL OR p_quantity <= 0 THEN
        RETURN QUERY SELECT -2, 'Invalid Quantity'::TEXT, NULL::INTEGER;
        RETURN;
    END IF;

    -- Check customer exists
    IF NOT EXISTS (SELECT 1 FROM customers WHERE customer_id = p_customer_id AND is_active = true) THEN
        RETURN QUERY SELECT -3, 'Customer not found or inactive'::TEXT, NULL::INTEGER;
        RETURN;
    END IF;

    -- Check stock availability
    SELECT stock_quantity INTO v_available_stock
    FROM products
    WHERE product_id = p_product_id;

    IF v_available_stock IS NULL THEN
        RETURN QUERY SELECT -4, 'Product not found'::TEXT, NULL::INTEGER;
        RETURN;
    END IF;

    IF v_available_stock < p_quantity THEN
        RETURN QUERY SELECT -5, 'Insufficient stock'::TEXT, NULL::INTEGER;
        RETURN;
    END IF;

    -- Process order within transaction
    INSERT INTO orders (customer_id, order_date, status)
    VALUES (p_customer_id, p_order_date, 'pending')
    RETURNING order_id INTO v_order_id;

    INSERT INTO order_items (order_id, product_id, quantity, unit_price)
    SELECT v_order_id, p_product_id, p_quantity, price
    FROM products
    WHERE product_id = p_product_id;

    UPDATE products
    SET stock_quantity = stock_quantity - p_quantity,
        last_modified = CURRENT_TIMESTAMP
    WHERE product_id = p_product_id;

    RETURN QUERY SELECT 0, 'Order created successfully'::TEXT, v_order_id;

EXCEPTION
    WHEN OTHERS THEN
        RETURN QUERY SELECT -999, SQLERRM::TEXT, NULL::INTEGER;
END;
$$;

Best Practices

Parameter Design

  • Use descriptive parameter names with consistent prefixes (@p_ or p_)
  • Provide default values where appropriate
  • Use OUTPUT parameters for result codes and messages
  • Group related parameters logically

Performance Optimization

  • Use SET NOCOUNT ON in T-SQL to reduce network traffic
  • Avoid SELECT * - specify required columns explicitly
  • Use EXISTS instead of COUNT(*) for existence checks
  • Consider using table-valued parameters for bulk operations

Maintenance and Documentation

  • Include header comments describing purpose, parameters, and return values
  • Use consistent naming conventions
  • Version control your procedures with change history
  • Include examples of procedure calls in comments

Security Considerations

  • Never build dynamic SQL with string concatenation
  • Use QUOTENAME() for dynamic object names in T-SQL
  • Implement role-based security where appropriate
  • Validate business rules within the procedure
  • Use stored procedures to enforce data access patterns

Common Patterns

Bulk Data Processing

CREATE TYPE CustomerOrderType AS TABLE
(
    CustomerId INT,
    ProductId INT,
    Quantity INT
);

CREATE PROCEDURE sp_ProcessBulkOrders
    @Orders CustomerOrderType READONLY
AS
BEGIN
    SET NOCOUNT ON;

    MERGE OrderItems AS target
    USING @Orders AS source
    ON target.CustomerId = source.CustomerId 
       AND target.ProductId = source.ProductId
    WHEN MATCHED THEN
        UPDATE SET Quantity = target.Quantity + source.Quantity
    WHEN NOT MATCHED THEN
        INSERT (CustomerId, ProductId, Quantity)
        VALUES (source.CustomerId, source.ProductId, source.Quantity);
END

Audit Trail Implementation

-- Always include audit fields in data modification procedures
UPDATE Customers
SET 
    CustomerName = @CustomerName,
    Email = @Email,
    LastModified = GETDATE(),
    ModifiedBy = SYSTEM_USER
WHERE CustomerId = @CustomerId;

-- Log the change
INSERT INTO CustomerAudit (CustomerId, Action, ModifiedBy, ModifiedDate, OldValues, NewValues)
VALUES (@CustomerId, 'UPDATE', SYSTEM_USER, GETDATE(), @OldValues, @NewValues);
Zambulay Спонсор

Карта для оплаты Claude, ChatGPT и других AI