package main import ( "database/sql" "fmt" "log" "os" _ "github.com/denisenkom/go-mssqldb" ) func main() { // Load DB connection settings from environment (set in docker‑compose) server := os.Getenv("DB_SERVER") user := os.Getenv("DB_USER") password := os.Getenv("DB_PASSWORD") dbName := os.Getenv("DB_NAME") if server == "" || user == "" || password == "" || dbName == "" { log.Fatalf("One or more DB environment variables are missing") } // Build the connection string for go‑mssqldb connStr := fmt.Sprintf("sqlserver://%s:%s@%s?database=%s", user, password, server, dbName) // Open a connection pool db, err := sql.Open("sqlserver", connStr) if err != nil { log.Fatalf("sql.Open failed: %v", err) } defer db.Close() // Verify the connection works if err = db.Ping(); err != nil { log.Fatalf("cannot ping database: %v", err) } fmt.Println("✅ Connected to MSSQL") // ----------------------------------------------------------------- // 1️⃣ Insert a new customer via the stored procedure sp_InsertCustomer // ----------------------------------------------------------------- var newCustID int insertCustSQL := ` DECLARE @NewID int; EXEC dbo.sp_InsertCustomer @CustomerName = @name, @AddressLine1 = @addr1, @AddressLine2 = @addr2, @City = @city, @State = @state, @ZipCode = @zip, @Country = @country, @NewCustomerID = @NewID OUTPUT; SELECT @NewID; ` row := db.QueryRow(insertCustSQL, sql.Named("name", "Acme Corp"), sql.Named("addr1", "123 Main St"), sql.Named("addr2", nil), sql.Named("city", "New York"), sql.Named("state", "NY"), sql.Named("zip", "10001"), sql.Named("country", "USA"), ) if err = row.Scan(&newCustID); err != nil { log.Fatalf("Insert customer failed: %v", err) } fmt.Printf("🆕 Inserted Customer ID: %d\n", newCustID) // ----------------------------------------------------------------- // 2️⃣ Insert a contact for the new customer via sp_InsertContact // ----------------------------------------------------------------- var newContactID int insertContactSQL := ` DECLARE @NewContactID int; EXEC dbo.sp_InsertContact @CustomerID = @custID, @ContactTypeID = @typeID, @ContactValue = @value, @IsPrimary = @primary, @NewContactID = @NewContactID OUTPUT; SELECT @NewContactID; ` // Assume ContactTypeID 1 = Phone (created by init.sql) row = db.QueryRow(insertContactSQL, sql.Named("custID", newCustID), sql.Named("typeID", 1), sql.Named("value", "555‑1234"), sql.Named("primary", 1), ) if err = row.Scan(&newContactID); err != nil { log.Fatalf("Insert contact failed: %v", err) } fmt.Printf("📞 Inserted Contact ID: %d\n", newContactID) // ----------------------------------------------------------------- // 3️⃣ Retrieve the customer via sp_GetCustomer // ----------------------------------------------------------------- var custName, addr1, addr2, city, state, zip, country string getCustSQL := `EXEC dbo.sp_GetCustomer @CustomerID = @id` err = db.QueryRow(getCustSQL, sql.Named("id", newCustID)).Scan( &newCustID, &custName, &addr1, &addr2, &city, &state, &zip, &country, &sql.NullTime{}, &sql.NullTime{}) if err != nil { log.Fatalf("Get customer failed: %v", err) } fmt.Printf("🔎 Fetched Customer: %s, %s, %s\n", custName, city, state) // ----------------------------------------------------------------- // 4️⃣ List contacts for the customer via sp_GetContactsByCustomer // ----------------------------------------------------------------- fmt.Println("📄 Contacts for the customer:") rows, err := db.Query(`EXEC dbo.sp_GetContactsByCustomer @CustomerID = @id`, sql.Named("id", newCustID)) if err != nil { log.Fatalf("Get contacts failed: %v", err) } defer rows.Close() for rows.Next() { var contactID, custID, ctID int var value string var isPrimary bool var typeName string if err = rows.Scan(&contactID, &custID, &ctID, &value, &isPrimary, &sql.NullTime{}, &sql.NullTime{}, &typeName); err != nil { log.Fatalf("Scanning contacts: %v", err) } fmt.Printf("- %s (%s) Primary:%v\n", value, typeName, isPrimary) } if err = rows.Err(); err != nil { log.Fatalf("Row iteration error: %v", err) } // ----------------------------------------------------------------- // 5️⃣ Update the customer name via sp_UpdateCustomer // ----------------------------------------------------------------- _, err = db.Exec(`EXEC dbo.sp_UpdateCustomer @CustomerID = @id, @CustomerName = @name, @AddressLine1 = @addr1, @AddressLine2 = @addr2, @City = @city, @State = @state, @ZipCode = @zip, @Country = @country`, sql.Named("id", newCustID), sql.Named("name", "Acme Corp – Updated"), sql.Named("addr1", "123 Main St"), sql.Named("addr2", nil), sql.Named("city", "New York"), sql.Named("state", "NY"), sql.Named("zip", "10001"), sql.Named("country", "USA"), ) if err != nil { log.Fatalf("Update customer failed: %v", err) } fmt.Println("✏️ Updated customer name") // ----------------------------------------------------------------- // 6️⃣ Delete the contact and the customer (cleanup) // ----------------------------------------------------------------- _, err = db.Exec(`EXEC dbo.sp_DeleteContact @ContactID = @cid`, sql.Named("cid", newContactID)) if err != nil { log.Fatalf("Delete contact failed: %v", err) } fmt.Println("🗑️ Deleted contact") _, err = db.Exec(`EXEC dbo.sp_DeleteCustomer @CustomerID = @cid`, sql.Named("cid", newCustID)) if err != nil { log.Fatalf("Delete customer failed: %v", err) } fmt.Println("🗑️ Deleted customer") fmt.Println("✅ All CRUD operations completed successfully") }