#!/bin/bash # Check if input file is provided if [ $# -ne 1 ]; then echo "Usage: $0 " exit 1 fi SQL_FILE="$1" BASE_DIR="sql_objects" # Create directory structure mkdir -p "$BASE_DIR/procedures" # Ensure proper permissions chmod -R 755 "$BASE_DIR" # Function to clean filename clean_filename() { # Remove brackets, convert dots and spaces to underscores, remove parentheses echo "$1" | sed 's/\[\|\]//g' | tr '.' '_' | tr ' ' '_' | sed 's/[()]//g' | sed 's/__*/_/g' | sed 's/_$//' } # Function to extract procedure name extract_procedure_name() { # More flexible procedure name extraction local name=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+(\[[^]]+\](\.[^]]+)?|\S+).*/\2/pi' | tr -d '[]') echo "$name" } # Function to extract schema name (if present) extract_schema_name() { # Extract schema name with more flexible matching local schema=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+\[?([^.]+)\.([^]]+)\]?.*/\2/pi') if [ -z "$schema" ]; then # Try alternative extraction schema=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+\[?([^]]+)\]?.*/\2/pi' | cut -d. -f1) fi if [ -z "$schema" ]; then echo "dbo" # Default schema if not specified else echo "$schema" | tr -d '[]' fi } # Function to process each procedure statement process_procedure() { local procedure_statement="$1" local procedure_name=$(extract_procedure_name "$procedure_statement") local schema_name=$(extract_schema_name "$procedure_statement") # Skip if we couldn't extract procedure name if [ -z "$procedure_name" ]; then echo "Warning: Could not extract procedure name from:" echo "$procedure_statement" return fi # Clean filename and save clean_name=$(clean_filename "${schema_name}_${procedure_name}") output_file="$BASE_DIR/procedures/${clean_name}.sql" # Trim whitespace and ensure semicolon at end if not already present procedure_statement=$(echo "$procedure_statement" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') if [[ "$procedure_statement" != *\; ]]; then procedure_statement="${procedure_statement};" fi # Save the procedure echo "$procedure_statement" > "$output_file" echo "Created: $output_file" } # Main processing function extract_procedures() { local current_statement="" local capturing_procedure=false local depth=0 # Disable case sensitivity shopt -s nocasematch # Read the file line by line while IFS= read -r line || [ -n "$line" ]; do # Skip empty lines and pure comment lines if [ -z "${line// }" ] || [[ "$line" =~ ^[[:space:]]*-- ]]; then continue fi # Check for procedure start (more flexible) if [[ "$line" =~ CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+ ]]; then # Process previous statement if any if [ -n "$current_statement" ] && $capturing_procedure; then process_procedure "$current_statement" fi # Start new procedure statement current_statement="$line" capturing_procedure=true depth=0 # Check if GO is on the same line if [[ "$line" =~ GO[[:space:]]*$ ]]; then # Remove GO and process current_statement=$(echo "$current_statement" | sed 's/[[:space:]]*GO[[:space:]]*$//') process_procedure "$current_statement" current_statement="" capturing_procedure=false fi continue fi # If we're capturing a procedure if $capturing_procedure; then # Track BEGIN/END blocks to ensure we capture the entire procedure if [[ "$line" =~ BEGIN ]]; then ((depth++)) fi if [[ "$line" =~ END ]]; then ((depth--)) fi # Add line to current statement current_statement+=" $line" # Check for GO statement or end of procedure if [[ "$line" =~ ^[[:space:]]*GO[[:space:]]*$ ]] || ([[ "$line" =~ END ]] && [[ $depth -le 0 ]]); then # Remove GO and process current_statement=$(echo "$current_statement" | sed 's/[[:space:]]*GO[[:space:]]*$//; s/;[[:space:]]*$//') process_procedure "$current_statement" current_statement="" capturing_procedure=false depth=0 fi fi done # Process any remaining procedure statement if [ -n "$current_statement" ] && $capturing_procedure; then process_procedure "$current_statement" fi # Re-enable case sensitivity shopt -u nocasematch } # Remove comment lines and process echo "Extracting stored procedures..." sed 's/--.*$//' "$SQL_FILE" | extract_procedures echo "Stored procedures have been saved in $BASE_DIR/procedures" # Count and list files count=$(ls -1 "$BASE_DIR/procedures"/*.sql 2>/dev/null | wc -l || echo 0) echo -e "\nTotal stored procedures extracted: $count" if [ "$count" -gt 0 ]; then echo -e "\nExtracted stored procedures:" for file in "$BASE_DIR/procedures"/*.sql; do if [ -f "$file" ]; then echo "- $(basename "$file")" fi done fi