mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
adding azure sql samples
Adding the samples content from extending the getting started website for azure specific workflows
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
# Developing applications with C# and Azure SQL
|
||||||
|
|
||||||
|
Pick a platform below to get started:
|
||||||
|
* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](linktodo)
|
||||||
|
* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/java/Windows)
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AzureSqlColumnstoreSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
System.Threading.Tasks.Task task = Program.DoWork(args);
|
||||||
|
// Becuase this program takes user input, have a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async System.Threading.Tasks.Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.WriteLine("*** Azure SQL Columnstore demo ***");
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault();
|
||||||
|
builder.InitialCatalog = "your_database";
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
string dropTable = "Drop table if exists Table_with_3M_rows";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTable, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Table cleaned up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 5 million rows into the table 'Table_with_3M_rows'
|
||||||
|
Console.Write("Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... ");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))");
|
||||||
|
sb.Append("SELECT TOP(3000000)");
|
||||||
|
sb.Append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ");
|
||||||
|
sb.Append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ");
|
||||||
|
sb.Append(",a.a * 10 AS Price ");
|
||||||
|
sb.Append(",CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName ");
|
||||||
|
sb.Append("INTO Table_with_3M_rows ");
|
||||||
|
sb.Append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute SQL query without columnstore index
|
||||||
|
double elapsedTimeWithoutIndex = SumPrice(connection);
|
||||||
|
Console.WriteLine("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms");
|
||||||
|
|
||||||
|
// Add a Columnstore Index
|
||||||
|
Console.Write("Adding a columnstore to table 'Table_with_3M_rows' ... ");
|
||||||
|
sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the same SQL query again after columnstore index was added
|
||||||
|
double elapsedTimeWithIndex = SumPrice(connection);
|
||||||
|
Console.WriteLine("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms");
|
||||||
|
|
||||||
|
// Calculate performance gain from adding columnstore index
|
||||||
|
Console.WriteLine("Performance improvement with columnstore index: "
|
||||||
|
+ Math.Round(elapsedTimeWithoutIndex / elapsedTimeWithIndex) + "x!");
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
string dropTable = "Drop table if exists Table_with_3M_rows";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTable, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Table cleaned up.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double SumPrice(SqlConnection connection)
|
||||||
|
{
|
||||||
|
String sql = "SELECT SUM(Price) FROM Table_with_3M_rows";
|
||||||
|
long startTicks = DateTime.Now.Ticks;
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sum = command.ExecuteScalar();
|
||||||
|
TimeSpan elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks) - TimeSpan.FromTicks(startTicks);
|
||||||
|
return elapsed.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.SqlServer;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class EFSampleContext : DbContext
|
||||||
|
{
|
||||||
|
string _connectionString;
|
||||||
|
public EFSampleContext(string connectionString)
|
||||||
|
{
|
||||||
|
this._connectionString = connectionString;
|
||||||
|
|
||||||
|
}
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseSqlServer(this._connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<Task> Tasks { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
+113
@@ -0,0 +1,113 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
System.Threading.Tasks.Task task = Program.DoWork(args);
|
||||||
|
// Becuase this program takes user input, have a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async System.Threading.Tasks.Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("** C# CRUD sample with Entity Framework and Azure SQL DB**\n");
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server_name.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault
|
||||||
|
builder.InitialCatalog = "your_db_name"; // Update me
|
||||||
|
|
||||||
|
using (EFSampleContext context = new EFSampleContext(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context.Database.EnsureDeleted();
|
||||||
|
context.Database.EnsureCreated();
|
||||||
|
Console.WriteLine("Created database schema from C# classes.");
|
||||||
|
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
Task newTask = new Task() { Title = "Ship Helsinki", IsComplete = false, DueDate = DateTime.Parse("04-01-2017") };
|
||||||
|
context.Tasks.Add(newTask);
|
||||||
|
context.SaveChanges();
|
||||||
|
Console.WriteLine("\nCreated Task: " + newTask.ToString());
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna'
|
||||||
|
Console.WriteLine("\nIncomplete tasks assigned to 'Anna':");
|
||||||
|
var query = from t in context.Tasks
|
||||||
|
where t.IsComplete == false &&
|
||||||
|
t.AssignedTo.FirstName.Equals("Anna")
|
||||||
|
select t;
|
||||||
|
foreach (var t in query)
|
||||||
|
{
|
||||||
|
Console.WriteLine(t.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
Task taskToUpdate = context.Tasks.First(); // get the first task
|
||||||
|
Console.WriteLine("\nUpdating task: " + taskToUpdate.ToString());
|
||||||
|
taskToUpdate.DueDate = DateTime.Parse("06-30-2016");
|
||||||
|
context.SaveChanges();
|
||||||
|
Console.WriteLine("dueDate changed: " + taskToUpdate.ToString());
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
Console.WriteLine("\nDeleting all tasks with a dueDate in 2016");
|
||||||
|
DateTime dueDate2016 = DateTime.Parse("12-31-2016");
|
||||||
|
List<Task> queryResults = context.Tasks.Where(t => t.DueDate < dueDate2016).ToList();
|
||||||
|
foreach (Task t in queryResults)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Deleting task: " + t.ToString());
|
||||||
|
context.Tasks.Remove(t);
|
||||||
|
}
|
||||||
|
context.SaveChanges();
|
||||||
|
|
||||||
|
// Show tasks after the 'Delete' operation - there should be 0 tasks
|
||||||
|
Console.WriteLine("\nTasks after delete:");
|
||||||
|
List<Task> tasksAfterDelete = (from t in context.Tasks select t).ToList<Task>();
|
||||||
|
if (tasksAfterDelete.Count == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[None]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Task t in query)
|
||||||
|
{
|
||||||
|
Console.WriteLine(t.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class Task
|
||||||
|
{
|
||||||
|
public int TaskId { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime DueDate { get; set; }
|
||||||
|
public bool IsComplete { get; set; }
|
||||||
|
public virtual User AssignedTo { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "Task [id=" + this.TaskId + ", title=" + this.Title + ", dueDate=" + this.DueDate.ToString() + ", IsComplete=" + this.IsComplete + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public String FirstName { get; set; }
|
||||||
|
public String LastName { get; set; }
|
||||||
|
public virtual IList<Task> Tasks { get; set; }
|
||||||
|
|
||||||
|
public String GetFullName()
|
||||||
|
{
|
||||||
|
return this.FirstName + " " + this.LastName;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "User [id=" + this.UserId + ", name=" + this.GetFullName() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
|
namespace AzureSqlSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server_name.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = "your_password"; // update me
|
||||||
|
builder.InitialCatalog = "your_database_name"; // update me
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
connection.Open();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
|
||||||
|
using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
Console.Write("Creating sample table with data, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("CREATE TABLE Employees ( ");
|
||||||
|
sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ");
|
||||||
|
sb.Append(" Name NVARCHAR(50), ");
|
||||||
|
sb.Append(" Location NVARCHAR(50) ");
|
||||||
|
sb.Append("); ");
|
||||||
|
sb.Append("INSERT INTO Employees (Name, Location) VALUES ");
|
||||||
|
sb.Append("(N'Jared', N'Australia'), ");
|
||||||
|
sb.Append("(N'Nikita', N'India'), ");
|
||||||
|
sb.Append("(N'Tom', N'Germany'); ");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
Console.Write("Inserting a new row into table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("INSERT Employees (Name, Location) ");
|
||||||
|
sb.Append("VALUES (@name, @location);");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", "Jake");
|
||||||
|
command.Parameters.AddWithValue("@location", "United States");
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToUpdate);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
Console.Write("Deleting user '" + userToDelete + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("DELETE FROM Employees WHERE Name = @name;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToDelete);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
Console.WriteLine("Reading data from table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
|
||||||
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.WriteLine("Cleaning up table.");
|
||||||
|
using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AzureSQLSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Task task = Program.DoWork(args);
|
||||||
|
// Becuase this program takes user input, have a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server_name.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user_id"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault
|
||||||
|
builder.InitialCatalog = "your_database"; // Update me
|
||||||
|
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
connection.Open();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Employees";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
Console.Write("Creating sample table with data, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("CREATE TABLE Employees ( ");
|
||||||
|
sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ");
|
||||||
|
sb.Append(" Name NVARCHAR(50), ");
|
||||||
|
sb.Append(" Location NVARCHAR(50) ");
|
||||||
|
sb.Append("); ");
|
||||||
|
sb.Append("INSERT INTO Employees (Name, Location) VALUES ");
|
||||||
|
sb.Append("(N'Jared', N'Australia'), ");
|
||||||
|
sb.Append("(N'Nikita', N'India'), ");
|
||||||
|
sb.Append("(N'Tom', N'Germany'); ");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
Console.Write("Inserting a new row into table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("INSERT Employees (Name, Location) ");
|
||||||
|
sb.Append("VALUES (@name, @location);");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", "Jake");
|
||||||
|
command.Parameters.AddWithValue("@location", "United States");
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToUpdate);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
Console.Write("Deleting user '" + userToDelete + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("DELETE FROM Employees WHERE Name = @name;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToDelete);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
Console.WriteLine("Reading data from table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
|
||||||
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.WriteLine("Cleaning up table.");
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Employees";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_key_vault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [C# tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AzureSQLSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Task task = Program.DoWork(args);
|
||||||
|
|
||||||
|
// Because this program waits for user input, use a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault
|
||||||
|
builder.InitialCatalog = "your_db"; // Update me
|
||||||
|
|
||||||
|
// Connect to SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Connect to SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
connection.Open();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Table_with_3M_rows";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 3 million rows into the table 'Table_with_3M_rows'
|
||||||
|
Console.Write("Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... ");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))");
|
||||||
|
sb.Append("SELECT TOP(3000000)");
|
||||||
|
sb.Append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ");
|
||||||
|
sb.Append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ");
|
||||||
|
sb.Append(",a.a * 10 AS Price ");
|
||||||
|
sb.Append(",CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName ");
|
||||||
|
sb.Append("INTO Table_with_3M_rows ");
|
||||||
|
sb.Append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute SQL query without columnstore index
|
||||||
|
double elapsedTimeWithoutIndex = SumPrice(connection);
|
||||||
|
Console.WriteLine("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms");
|
||||||
|
|
||||||
|
// Add a Columnstore Index
|
||||||
|
Console.Write("Adding a columnstore to table 'Table_with_3M_rows' ... ");
|
||||||
|
sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the same SQL query again after columnstore index was added
|
||||||
|
double elapsedTimeWithIndex = SumPrice(connection);
|
||||||
|
Console.WriteLine("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms");
|
||||||
|
|
||||||
|
// Calculate performance gain from adding columnstore index
|
||||||
|
Console.WriteLine("Performance improvement with columnstore index: "
|
||||||
|
+ Math.Round(elapsedTimeWithoutIndex / elapsedTimeWithIndex) + "x!");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Table_with_3M_rows";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double SumPrice(SqlConnection connection)
|
||||||
|
{
|
||||||
|
String sql = "SELECT SUM(Price) FROM Table_with_3M_rows";
|
||||||
|
long startTicks = DateTime.Now.Ticks;
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sum = command.ExecuteScalar();
|
||||||
|
TimeSpan elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks) - TimeSpan.FromTicks(startTicks);
|
||||||
|
return elapsed.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://you_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.Entity;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class EFSampleContext : DbContext
|
||||||
|
{
|
||||||
|
public EFSampleContext(string connectionString)
|
||||||
|
{
|
||||||
|
Database.SetInitializer<EFSampleContext>(new CreateDatabaseIfNotExists<EFSampleContext>());
|
||||||
|
this.Database.Connection.ConnectionString = connectionString;
|
||||||
|
}
|
||||||
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<Task> Tasks { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
System.Threading.Tasks.Task task = Program.DoWork(args);
|
||||||
|
// Becuase this program takes user input, have a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async System.Threading.Tasks.Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
Console.WriteLine("** C# CRUD sample with Entity Framework and Azure SQL **\n");
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault
|
||||||
|
builder.InitialCatalog = "your_db"; // Update me
|
||||||
|
|
||||||
|
using (EFSampleContext context = new EFSampleContext(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
Task newTask = new Task() { Title = "Ship Helsinki", IsComplete = false, DueDate = DateTime.Parse("04-01-2017") };
|
||||||
|
context.Tasks.Add(newTask);
|
||||||
|
context.SaveChanges();
|
||||||
|
Console.WriteLine("\nCreated Task: " + newTask.ToString());
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna'
|
||||||
|
Console.WriteLine("\nIncomplete tasks assigned to 'Anna':");
|
||||||
|
var query = from t in context.Tasks
|
||||||
|
where t.IsComplete == false &&
|
||||||
|
t.AssignedTo.FirstName.Equals("Anna")
|
||||||
|
select t;
|
||||||
|
foreach (var t in query)
|
||||||
|
{
|
||||||
|
Console.WriteLine(t.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
Task taskToUpdate = context.Tasks.First(); // get the first task
|
||||||
|
Console.WriteLine("\nUpdating task: " + taskToUpdate.ToString());
|
||||||
|
taskToUpdate.DueDate = DateTime.Parse("06-30-2016");
|
||||||
|
context.SaveChanges();
|
||||||
|
Console.WriteLine("dueDate changed: " + taskToUpdate.ToString());
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
Console.WriteLine("\nDeleting all tasks with a dueDate in 2016");
|
||||||
|
DateTime dueDate2016 = DateTime.Parse("12-31-2016");
|
||||||
|
List<Task> queryResults = context.Tasks.Where(t => t.DueDate < dueDate2016).ToList();
|
||||||
|
foreach (Task t in queryResults)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Deleting task: " + t.ToString());
|
||||||
|
context.Tasks.Remove(t);
|
||||||
|
}
|
||||||
|
context.SaveChanges();
|
||||||
|
|
||||||
|
// Show tasks after the 'Delete' operation - there should be 0 tasks
|
||||||
|
Console.WriteLine("\nTasks after delete:");
|
||||||
|
List<Task> tasksAfterDelete = (from t in context.Tasks select t).ToList<Task>();
|
||||||
|
if (tasksAfterDelete.Count == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[None]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Task t in query)
|
||||||
|
{
|
||||||
|
Console.WriteLine(t.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class Task
|
||||||
|
{
|
||||||
|
public int TaskId { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime DueDate { get; set; }
|
||||||
|
public bool IsComplete { get; set; }
|
||||||
|
public virtual User AssignedTo { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "Task [id=" + this.TaskId + ", title=" + this.Title + ", dueDate=" + this.DueDate.ToString() + ", IsComplete=" + this.IsComplete + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AzureSqlEFSample
|
||||||
|
{
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public String FirstName { get; set; }
|
||||||
|
public String LastName { get; set; }
|
||||||
|
public virtual IList<Task> Tasks { get; set; }
|
||||||
|
|
||||||
|
public String GetFullName()
|
||||||
|
{
|
||||||
|
return this.FirstName + " " + this.LastName;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "User [id=" + this.UserId + ", name=" + this.GetFullName() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
|
namespace AzureSqlSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server_name.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user"; // update me
|
||||||
|
builder.Password = "your_password"; // update me
|
||||||
|
builder.InitialCatalog = "your_database_name"; // update me
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
connection.Open();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
|
||||||
|
using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
Console.Write("Creating sample table with data, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("CREATE TABLE Employees ( ");
|
||||||
|
sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ");
|
||||||
|
sb.Append(" Name NVARCHAR(50), ");
|
||||||
|
sb.Append(" Location NVARCHAR(50) ");
|
||||||
|
sb.Append("); ");
|
||||||
|
sb.Append("INSERT INTO Employees (Name, Location) VALUES ");
|
||||||
|
sb.Append("(N'Jared', N'Australia'), ");
|
||||||
|
sb.Append("(N'Nikita', N'India'), ");
|
||||||
|
sb.Append("(N'Tom', N'Germany'); ");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
Console.Write("Inserting a new row into table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("INSERT Employees (Name, Location) ");
|
||||||
|
sb.Append("VALUES (@name, @location);");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", "Jake");
|
||||||
|
command.Parameters.AddWithValue("@location", "United States");
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToUpdate);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
Console.Write("Deleting user '" + userToDelete + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("DELETE FROM Employees WHERE Name = @name;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToDelete);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
Console.WriteLine("Reading data from table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
|
||||||
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.WriteLine("Cleaning up table.");
|
||||||
|
using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using Microsoft.Azure.KeyVault;
|
||||||
|
using Microsoft.Azure.KeyVault.Models;
|
||||||
|
using Microsoft.Azure.Services.AppAuthentication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AzureSQLSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Task task = Program.DoWork(args);
|
||||||
|
// Becuase this program takes user input, have a long wait.
|
||||||
|
var result = task.Wait(TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task DoWork(string[] args)
|
||||||
|
{
|
||||||
|
string sql;
|
||||||
|
|
||||||
|
// Build connection string
|
||||||
|
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||||
|
builder.DataSource = "your_server_name.database.windows.net"; // update me
|
||||||
|
builder.UserID = "your_user_id"; // update me
|
||||||
|
builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault
|
||||||
|
builder.InitialCatalog = "your_database"; // Update me
|
||||||
|
|
||||||
|
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Connect to Azure SQL
|
||||||
|
Console.Write("Connecting to Azure SQL ... ");
|
||||||
|
connection.Open();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Employees";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
Console.Write("Creating sample table with data, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("CREATE TABLE Employees ( ");
|
||||||
|
sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ");
|
||||||
|
sb.Append(" Name NVARCHAR(50), ");
|
||||||
|
sb.Append(" Location NVARCHAR(50) ");
|
||||||
|
sb.Append("); ");
|
||||||
|
sb.Append("INSERT INTO Employees (Name, Location) VALUES ");
|
||||||
|
sb.Append("(N'Jared', N'Australia'), ");
|
||||||
|
sb.Append("(N'Nikita', N'India'), ");
|
||||||
|
sb.Append("(N'Tom', N'Germany'); ");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
Console.Write("Inserting a new row into table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("INSERT Employees (Name, Location) ");
|
||||||
|
sb.Append("VALUES (@name, @location);");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", "Jake");
|
||||||
|
command.Parameters.AddWithValue("@location", "United States");
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToUpdate);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
Console.Write("Deleting user '" + userToDelete + "', press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("DELETE FROM Employees WHERE Name = @name;");
|
||||||
|
sql = sb.ToString();
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@name", userToDelete);
|
||||||
|
int rowsAffected = command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
Console.WriteLine("Reading data from table, press any key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
using (SqlCommand command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
|
||||||
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.WriteLine("Cleaning up table.");
|
||||||
|
string dropTableIfExists = @"DROP TABLE IF EXISTS Employees";
|
||||||
|
using (SqlCommand command = new SqlCommand(dropTableIfExists, connection))
|
||||||
|
{
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
Console.WriteLine("Done.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All done. Press any key to finish...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> GetPasswordFromKeyVault()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue...");
|
||||||
|
Console.ReadKey(true);
|
||||||
|
/* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */
|
||||||
|
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
|
||||||
|
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
|
||||||
|
SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_key_vault_name.vault.azure.net/secrets/AppSecret"); // update me
|
||||||
|
return secret.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [C# on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp/windows/az) to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Developing applications with Go and Azure SQL
|
||||||
|
|
||||||
|
This information is meant to pair with the steps from [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/), so please follow along there.
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
|
"database/sql"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var server = "your_server.database.windows.net"
|
||||||
|
var user = "your_user"
|
||||||
|
var password = "your_password"
|
||||||
|
var database = "your_database"
|
||||||
|
|
||||||
|
var db *sql.DB
|
||||||
|
|
||||||
|
// Delete an employee from database
|
||||||
|
func ExecuteAggregateStatement(db *sql.DB) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Ping database to see if it's still alive.
|
||||||
|
// Important for handling network issues and long queries.
|
||||||
|
err := db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error pinging database: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var result string
|
||||||
|
|
||||||
|
// Execute long non-query to aggregate rows
|
||||||
|
err = db.QueryRowContext(ctx, "SELECT SUM(Price) as sum FROM Table_with_3M_rows").Scan(&result)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error executing query: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Sum: %s\n", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to database
|
||||||
|
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;",
|
||||||
|
server, user, password, database)
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Create connection pool
|
||||||
|
db, err = sql.Open("sqlserver", connString)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Open connection failed:", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Connected!\n")
|
||||||
|
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
t1 := time.Now()
|
||||||
|
fmt.Printf("Start time: %s\n", t1)
|
||||||
|
|
||||||
|
ExecuteAggregateStatement(db)
|
||||||
|
|
||||||
|
t2 := time.Since(t1)
|
||||||
|
fmt.Printf("The query took: %s\n", t2)
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
|
"database/sql"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Replace with your own connection parameters
|
||||||
|
var server = "your_server.database.windows.net"
|
||||||
|
var user = "your_user"
|
||||||
|
var password = "your_password"
|
||||||
|
var database = "your_database"
|
||||||
|
|
||||||
|
var db *sql.DB
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Create connection string
|
||||||
|
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s",
|
||||||
|
server, user, password, database)
|
||||||
|
|
||||||
|
// Create connection pool
|
||||||
|
db, err = sql.Open("sqlserver", connString)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error creating connection pool: " + err.Error())
|
||||||
|
}
|
||||||
|
log.Printf("Connected!\n")
|
||||||
|
|
||||||
|
// Close the database connection pool after program executes
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
SelectVersion()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets and prints SQL Server version
|
||||||
|
func SelectVersion(){
|
||||||
|
// Use background context
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Ping database to see if it's still alive.
|
||||||
|
// Important for handling network issues and long queries.
|
||||||
|
err := db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error pinging database: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var result string
|
||||||
|
|
||||||
|
// Run query and scan for result
|
||||||
|
err = db.QueryRowContext(ctx, "SELECT @@version").coScan(&result)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Scan failed:", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", result)
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
|
"database/sql"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var db *sql.DB
|
||||||
|
|
||||||
|
// Replace with your own connection parameters
|
||||||
|
var server = "your_server.database.windows.net"
|
||||||
|
var user = "your_user"
|
||||||
|
var password = "your_password"
|
||||||
|
var database = "your_database"
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Build connection string
|
||||||
|
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;",
|
||||||
|
server, user, password, database)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Create connection pool
|
||||||
|
db, err = sql.Open("sqlserver", connString)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error creating connection pool: ", err.Error())
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
err = db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Connected!\n")
|
||||||
|
|
||||||
|
// Create employee
|
||||||
|
createID, err := CreateEmployee("Jake", "United States")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error creating Employee: ", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Inserted ID: %d successfully.\n", createID)
|
||||||
|
|
||||||
|
// Read employees
|
||||||
|
count, err := ReadEmployees()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading Employees: ", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Read %d row(s) successfully.\n", count)
|
||||||
|
|
||||||
|
// Update from database
|
||||||
|
updatedRows, err := UpdateEmployee("Jake", "Poland")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error updating Employee: ", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Updated %d row(s) successfully.\n", updatedRows)
|
||||||
|
|
||||||
|
// Delete from database
|
||||||
|
deletedRows, err := DeleteEmployee("Jake")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error deleting Employee: ", err.Error())
|
||||||
|
}
|
||||||
|
fmt.Printf("Deleted %d row(s) successfully.\n", deletedRows)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateEmployee inserts an employee record
|
||||||
|
func CreateEmployee(name string, location string) (int64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if db == nil {
|
||||||
|
err = errors.New("CreateEmployee: db is null")
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if database is alive.
|
||||||
|
err = db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsql := "INSERT INTO TestSchema.Employees (Name, Location) VALUES (@Name, @Location); select convert(bigint, SCOPE_IDENTITY());"
|
||||||
|
|
||||||
|
stmt, err := db.Prepare(tsql)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
row := stmt.QueryRowContext(
|
||||||
|
ctx,
|
||||||
|
sql.Named("Name", name),
|
||||||
|
sql.Named("Location", location))
|
||||||
|
var newID int64
|
||||||
|
err = row.Scan(&newID)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return newID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadEmployees reads all employee records
|
||||||
|
func ReadEmployees() (int, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Check if database is alive.
|
||||||
|
err := db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsql := fmt.Sprintf("SELECT Id, Name, Location FROM TestSchema.Employees;")
|
||||||
|
|
||||||
|
// Execute query
|
||||||
|
rows, err := db.QueryContext(ctx, tsql)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var count int
|
||||||
|
|
||||||
|
// Iterate through the result set.
|
||||||
|
for rows.Next() {
|
||||||
|
var name, location string
|
||||||
|
var id int
|
||||||
|
|
||||||
|
// Get values from row.
|
||||||
|
err := rows.Scan(&id, &name, &location)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("ID: %d, Name: %s, Location: %s\n", id, name, location)
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEmployee updates an employee's information
|
||||||
|
func UpdateEmployee(name string, location string) (int64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Check if database is alive.
|
||||||
|
err := db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsql := fmt.Sprintf("UPDATE TestSchema.Employees SET Location = @Location WHERE Name = @Name")
|
||||||
|
|
||||||
|
// Execute non-query with named parameters
|
||||||
|
result, err := db.ExecContext(
|
||||||
|
ctx,
|
||||||
|
tsql,
|
||||||
|
sql.Named("Location", location),
|
||||||
|
sql.Named("Name", name))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.RowsAffected()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteEmployee deletes an employee from the database
|
||||||
|
func DeleteEmployee(name string) (int64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Check if database is alive.
|
||||||
|
err := db.PingContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsql := fmt.Sprintf("DELETE FROM TestSchema.Employees WHERE Name = @Name;")
|
||||||
|
|
||||||
|
// Execute non-query with named parameters
|
||||||
|
result, err := db.ExecContext(ctx, tsql, sql.Named("Name", name))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.RowsAffected()
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mssql"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var server = "your_server.database.windows.net"
|
||||||
|
var user = "your_user"
|
||||||
|
var password = "your_password"
|
||||||
|
var database = "your_database"
|
||||||
|
|
||||||
|
// Define a User model struct
|
||||||
|
type User struct {
|
||||||
|
gorm.Model
|
||||||
|
FirstName string
|
||||||
|
LastName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a Task model struct
|
||||||
|
type Task struct {
|
||||||
|
gorm.Model
|
||||||
|
Title string
|
||||||
|
DueDate string
|
||||||
|
IsComplete bool
|
||||||
|
UserID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and print all the tasks
|
||||||
|
func ReadAllTasks(db *gorm.DB){
|
||||||
|
var users []User
|
||||||
|
var tasks []Task
|
||||||
|
db.Find(&users)
|
||||||
|
|
||||||
|
for _, user := range users{
|
||||||
|
db.Model(&user).Related(&tasks)
|
||||||
|
fmt.Printf("%s %s's tasks:\n", user.FirstName, user.LastName)
|
||||||
|
for _, task := range tasks {
|
||||||
|
fmt.Printf("Title: %s\nDueDate: %s\nIsComplete:%t\n\n",
|
||||||
|
task.Title, task.DueDate, task.IsComplete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update a task based on a user
|
||||||
|
func UpdateSomeonesTask(db *gorm.DB, userId int){
|
||||||
|
var task Task
|
||||||
|
db.Where("user_id = ?", userId).First(&task).Update("Title", "Buy donuts for Luis")
|
||||||
|
fmt.Printf("Title: %s\nDueDate: %s\nIsComplete:%t\n\n",
|
||||||
|
task.Title, task.DueDate, task.IsComplete)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all the tasks for a user
|
||||||
|
func DeleteSomeonesTasks(db *gorm.DB, userId int){
|
||||||
|
db.Where("user_id = ?", userId).Delete(&Task{})
|
||||||
|
fmt.Printf("Deleted all tasks for user %d", userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
connectionString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s",
|
||||||
|
server, user, password, database)
|
||||||
|
db, err := gorm.Open("mssql", connectionString)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to create connection pool. Error: " + err.Error())
|
||||||
|
}
|
||||||
|
gorm.DefaultCallback.Create().Remove("mssql:set_identity_insert")
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
fmt.Println("Migrating models...")
|
||||||
|
db.AutoMigrate(&User{})
|
||||||
|
db.AutoMigrate(&Task{})
|
||||||
|
|
||||||
|
// Create awesome Users
|
||||||
|
fmt.Println("Creating awesome users...")
|
||||||
|
db.Create(&User{FirstName: "Andrea", LastName: "Lam"}) //UserID: 1
|
||||||
|
db.Create(&User{FirstName: "Meet", LastName: "Bhagdev"}) //UserID: 2
|
||||||
|
db.Create(&User{FirstName: "Luis", LastName: "Bosquez"}) //UserID: 3
|
||||||
|
|
||||||
|
// Create appropriate Tasks for each user
|
||||||
|
fmt.Println("Creating new appropriate tasks...")
|
||||||
|
db.Create(&Task{
|
||||||
|
Title: "Do laundry", DueDate: "2021-03-30", IsComplete: false, UserID: 1})
|
||||||
|
db.Create(&Task{
|
||||||
|
Title: "Mow the lawn", DueDate: "2021-03-30", IsComplete: false, UserID: 2})
|
||||||
|
db.Create(&Task{
|
||||||
|
Title: "Do more laundry", DueDate: "2021-03-30", IsComplete: false, UserID: 3})
|
||||||
|
db.Create(&Task{
|
||||||
|
Title: "Watch TV", DueDate: "2021-03-30", IsComplete: false, UserID: 3})
|
||||||
|
|
||||||
|
// Read
|
||||||
|
fmt.Println("\nReading all the tasks...")
|
||||||
|
ReadAllTasks(db)
|
||||||
|
|
||||||
|
// Update - update Task title to something more appropriate
|
||||||
|
fmt.Println("Updating Andrea's task...")
|
||||||
|
UpdateSomeonesTask(db, 1)
|
||||||
|
|
||||||
|
// Delete - delete Luis's task
|
||||||
|
DeleteSomeonesTasks(db, 3)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Developing applications with Java and Azure SQL
|
||||||
|
|
||||||
|
Pick a platform below to get started:
|
||||||
|
* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based)
|
||||||
|
* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows)
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("*** Azure SQL Columnstore demo ***");
|
||||||
|
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue();
|
||||||
|
|
||||||
|
// Load SQL Server JDBC driver and establish connection.
|
||||||
|
try {
|
||||||
|
// Load SQL Server JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Create an example database
|
||||||
|
System.out.print("Dropping Table if already created ... ");
|
||||||
|
String sql = "DROP TABLE IF EXISTS [Table_with_3M_rows];";
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
// Insert 3 million rows into the table 'Table_with_3M_rows'
|
||||||
|
System.out.print(
|
||||||
|
"Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... ");
|
||||||
|
sql = new StringBuilder()
|
||||||
|
.append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))")
|
||||||
|
.append("SELECT TOP(5000000)").append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ")
|
||||||
|
.append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ")
|
||||||
|
.append(",a.a * 10 AS Price ")
|
||||||
|
.append(",CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName ")
|
||||||
|
.append("INTO Table_with_3M_rows ")
|
||||||
|
.append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute SQL query without a columnstore index
|
||||||
|
long elapsedTimeWithoutIndex = SumPrice(connection);
|
||||||
|
System.out.println("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms");
|
||||||
|
|
||||||
|
System.out.print("Adding a columnstore to table 'Table_with_3M_rows' ... ");
|
||||||
|
sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;";
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the same SQL query again after the columnstore index
|
||||||
|
// is added
|
||||||
|
long elapsedTimeWithIndex = SumPrice(connection);
|
||||||
|
System.out.println("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms");
|
||||||
|
|
||||||
|
// Calculate performance gain from adding columnstore index
|
||||||
|
System.out.println("Performance improvement with columnstore index: "
|
||||||
|
+ elapsedTimeWithoutIndex / elapsedTimeWithIndex + "x!");
|
||||||
|
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)){
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("Drop table if exists Table_with_3M_rows");
|
||||||
|
System.out.println("Table cleaned up.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long SumPrice(Connection connection) {
|
||||||
|
String sql = "SELECT SUM(Price) FROM Table_with_3M_rows;";
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
long elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
return elapsedTime;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlColumnstoreSample</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>AzureSqlColumnstoreSample</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- add the JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Add Key Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<!-- specify which version of Java to build against-->
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
+169
@@ -0,0 +1,169 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java CRUD sample with Hibernate and Azure SQL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class App {
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net"; // update me
|
||||||
|
String userName = "your_user"; // update me
|
||||||
|
String password = "Will_Be_Updated_From_Key_Vault";
|
||||||
|
String sampleDatabaseName = "your_db"; // update me
|
||||||
|
|
||||||
|
// Main entry point
|
||||||
|
public static void main(String[] args) {
|
||||||
|
App app = new App();
|
||||||
|
app.runDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to run the demp app
|
||||||
|
public void runDemo()
|
||||||
|
{
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_key_vault.vault.azure.net/") // Update me
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
password = secret.getValue();
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Configure Hibernate logging to only log SEVERE errors
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger("org.hibernate");
|
||||||
|
java.util.logging.Logger.getLogger("org.hibernate").setLevel(java.util.logging.Level.SEVERE);
|
||||||
|
|
||||||
|
System.out.println("**Java CRUD sample with Hibernate and Azure SQL **\n");
|
||||||
|
try {
|
||||||
|
// We're creating the Hibernate configuration via code. An alternative is to use a 'hibernate.cfg.xml' file.
|
||||||
|
Configuration cfg = createHibernateConfiguration();
|
||||||
|
|
||||||
|
// We're mapping POJO classes to Tables via Hibernate Annotations. An alternative is to use Hibernate mapping xml files.
|
||||||
|
cfg.addAnnotatedClass(User.class);
|
||||||
|
cfg.addAnnotatedClass(Task.class);
|
||||||
|
|
||||||
|
System.out.println("added classes to config");
|
||||||
|
|
||||||
|
|
||||||
|
// Hibernate needs an existing database. We already have one created.
|
||||||
|
|
||||||
|
// Create the Hibernate SessionFactory and Session.
|
||||||
|
// This causes Hibernate to create Tables and Relationships in the database from our Annotated classes.
|
||||||
|
try (SessionFactory sessionFactory = cfg.buildSessionFactory();
|
||||||
|
Session session = sessionFactory.openSession()) {
|
||||||
|
|
||||||
|
System.out.println("Created database schema from Java classes.\n");
|
||||||
|
session.beginTransaction();
|
||||||
|
|
||||||
|
// Create demo: Create a User instance and save it to the database
|
||||||
|
User newUser = new User("Anna", "Shrestinian");
|
||||||
|
session.save(newUser);
|
||||||
|
System.out.println("Created User: " + newUser.toString());
|
||||||
|
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
|
||||||
|
Task newTask = new Task("Ship Helsinki", sdf.parse("04-01-2017"));
|
||||||
|
session.save(newTask);
|
||||||
|
System.out.println("Created Task: " + newTask.toString());
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
newTask.setUser(newUser);
|
||||||
|
session.save(newTask);
|
||||||
|
System.out.println("Assigned Task: '" + newTask.getTitle() + "' to user '" + newUser.getFullName() + "'\n");
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna'
|
||||||
|
System.out.println("Incomplete tasks assigned to 'Anna':");
|
||||||
|
String hqlQuery = "from Task where isComplete = false and user.firstName = :paramFirstName";
|
||||||
|
List<Task> incompleteTasks = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.setParameter("paramFirstName", "Anna")
|
||||||
|
.getResultList();
|
||||||
|
for(Task theTask : incompleteTasks) {
|
||||||
|
System.out.println(theTask.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
hqlQuery = "from Task";
|
||||||
|
Task taskToUpdate = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.getResultList()
|
||||||
|
.get(0); // get the first task
|
||||||
|
System.out.println("\nUpdating task: " + taskToUpdate.toString());
|
||||||
|
taskToUpdate.setDueDate(sdf.parse("06-30-2016"));
|
||||||
|
session.save(taskToUpdate);
|
||||||
|
System.out.println("dueDate changed: " + taskToUpdate.toString());
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
System.out.println("\nDeleting all tasks with a dueDate in 2016");
|
||||||
|
hqlQuery = "from Task where dueDate < :paramDate";
|
||||||
|
List<Task> tasksToDelete = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.setParameter("paramDate", sdf.parse("12-31-2016"))
|
||||||
|
.getResultList();
|
||||||
|
for(Task theTask : tasksToDelete) {
|
||||||
|
System.out.println("Deleting task:" + theTask.toString());
|
||||||
|
session.delete(theTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show tasks after the 'Delete' operation - there should be 0 tasks
|
||||||
|
System.out.println("\nTasks after delete:");
|
||||||
|
hqlQuery = "from Task";
|
||||||
|
List<Task> tasksAfterDelete = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.getResultList();
|
||||||
|
if(tasksAfterDelete.isEmpty()) {
|
||||||
|
System.out.println("[None]");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(Task theTask : tasksAfterDelete) {
|
||||||
|
System.out.println(theTask.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
}
|
||||||
|
System.out.println("All done.");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Hibernate configuration via code instead of using a
|
||||||
|
// 'hibernate.cfg.xml' file.
|
||||||
|
private Configuration createHibernateConfiguration() {
|
||||||
|
String url = this.connectionUrl + ";databaseName=" + this.sampleDatabaseName;
|
||||||
|
Configuration cfg = new Configuration()
|
||||||
|
.setProperty("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
|
||||||
|
.setProperty("hibernate.connection.url", url)
|
||||||
|
.setProperty("hibernate.connection.username", this.userName)
|
||||||
|
.setProperty("hibernate.connection.password", this.password)
|
||||||
|
.setProperty("hibernate.connection.autocommit", "true")
|
||||||
|
.setProperty("hibernate.show_sql", "false");
|
||||||
|
|
||||||
|
// Tell Hibernate to use the 'SQL Server' dialect when dynamically
|
||||||
|
// generating SQL queries
|
||||||
|
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
|
||||||
|
|
||||||
|
// Tell Hibernate to show the generated T-SQL
|
||||||
|
cfg.setProperty("hibernate.show_sql", "false");
|
||||||
|
|
||||||
|
// This is ok during development, but not recommended in production
|
||||||
|
// See: http://stackoverflow.com/questions/221379/hibernate-hbm2ddl-auto-update-in-production
|
||||||
|
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "Tasks")
|
||||||
|
public class Task {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id", updatable = false, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
private String title;
|
||||||
|
private Boolean isComplete;
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date dueDate;
|
||||||
|
|
||||||
|
// Specify a Many:1 mapping between Task and User
|
||||||
|
@ManyToOne
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Task() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task(String title, Date dueDate) {
|
||||||
|
this.title = title;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
this.isComplete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task(String title, Date dueDate, User user) {
|
||||||
|
this.title = title;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
this.isComplete = false;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return this.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDueDate() {
|
||||||
|
return this.dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDueDate(Date dueDate) {
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
|
||||||
|
return "Task [id=" + this.id + ", title=" + this.title + ", dueDate=" + ft.format(this.dueDate)
|
||||||
|
+ ", isComplete=" + this.isComplete.toString() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "Users")
|
||||||
|
public class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id", updatable = false, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
// Specify a 1:Many mapping between User and Task via the "user" field in
|
||||||
|
// the "Tasks" class.
|
||||||
|
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
|
||||||
|
private List<Task> tasks = new ArrayList<Task>();
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String firstName, String lastName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return this.firstName + " " + this.lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTasks(List<Task> tasks) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User [id=" + this.id + ", name=" + this.getFullName() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlHibernateSample</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>AzureSqlHibernateSample</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- add the JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- add Hibernate -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>5.2.3.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.javassist</groupId>
|
||||||
|
<artifactId>javassist</artifactId>
|
||||||
|
<version>3.23.1-GA</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Add Key Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server_name.database.windows.net;databaseName=your_database_name;user=your_user;password=your_password";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load SQL Server JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Create a sample database
|
||||||
|
System.out.print("Dropping Employees table if exists ... ");
|
||||||
|
String sql = "DROP Table IF EXISTS Employees";
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
System.out.println("Creating sample table with data, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = new StringBuilder().append("CREATE TABLE Employees ( ")
|
||||||
|
.append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ")
|
||||||
|
.append(" Location NVARCHAR(50) ").append("); ")
|
||||||
|
.append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ")
|
||||||
|
.append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
System.out.println("Inserting a new row into table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);")
|
||||||
|
.toString();
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, "Jake");
|
||||||
|
statement.setString(2, "United States");
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToUpdate);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
System.out.println("Deleting user '" + userToDelete + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "DELETE FROM Employees WHERE Name = ?;";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToDelete);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
System.out.println("Reading data from table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
try (Statement statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
System.out.println(
|
||||||
|
resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close();
|
||||||
|
System.out.println("All done.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
String sql = "DROP Table IF EXISTS Employees";
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Table dropped.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load Azure SQL JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Done.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
System.out.print("Creating sample table with data, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
String sql = new StringBuilder().append("CREATE TABLE Employees ( ")
|
||||||
|
.append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ")
|
||||||
|
.append(" Location NVARCHAR(50) ").append("); ")
|
||||||
|
.append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ")
|
||||||
|
.append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
System.out.print("Inserting a new row into table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);")
|
||||||
|
.toString();
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, "Jake");
|
||||||
|
statement.setString(2, "United States");
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToUpdate);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "DELETE FROM Employees WHERE Name = ?;";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToDelete);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
System.out.print("Reading data from table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
try (Statement statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
System.out.println(
|
||||||
|
resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close();
|
||||||
|
System.out.println("All done.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)){
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Table cleaned up.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlSample</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<name>AzureSqlSample</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [Java tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("*** Azure SQL Columnstore demo ***");
|
||||||
|
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue();
|
||||||
|
|
||||||
|
// Load SQL Server JDBC driver and establish connection.
|
||||||
|
try {
|
||||||
|
// Load SQL Server JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Create an example database
|
||||||
|
System.out.print("Dropping Table if already created ... ");
|
||||||
|
String sql = "DROP TABLE IF EXISTS [Table_with_3M_rows];";
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
// Insert 3 million rows into the table 'Table_with_3M_rows'
|
||||||
|
System.out.print(
|
||||||
|
"Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... ");
|
||||||
|
sql = new StringBuilder()
|
||||||
|
.append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))")
|
||||||
|
.append("SELECT TOP(5000000)").append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ")
|
||||||
|
.append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ")
|
||||||
|
.append(",a.a * 10 AS Price ")
|
||||||
|
.append(",CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName ")
|
||||||
|
.append("INTO Table_with_3M_rows ")
|
||||||
|
.append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute SQL query without a columnstore index
|
||||||
|
long elapsedTimeWithoutIndex = SumPrice(connection);
|
||||||
|
System.out.println("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms");
|
||||||
|
|
||||||
|
System.out.print("Adding a columnstore to table 'Table_with_3M_rows' ... ");
|
||||||
|
sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;";
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the same SQL query again after the columnstore index
|
||||||
|
// is added
|
||||||
|
long elapsedTimeWithIndex = SumPrice(connection);
|
||||||
|
System.out.println("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms");
|
||||||
|
|
||||||
|
// Calculate performance gain from adding columnstore index
|
||||||
|
System.out.println("Performance improvement with columnstore index: "
|
||||||
|
+ elapsedTimeWithoutIndex / elapsedTimeWithIndex + "x!");
|
||||||
|
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)){
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("Drop table if exists Table_with_3M_rows");
|
||||||
|
System.out.println("Table cleaned up.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long SumPrice(Connection connection) {
|
||||||
|
String sql = "SELECT SUM(Price) FROM Table_with_3M_rows;";
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
long elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
return elapsedTime;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlColumnstoreSample</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>AzureSqlColumnstoreSample</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- add the JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Add Key Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<!-- specify which version of Java to build against-->
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
+169
@@ -0,0 +1,169 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java CRUD sample with Hibernate and Azure SQL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class App {
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net"; // update me
|
||||||
|
String userName = "your_user"; // update me
|
||||||
|
String password = "Will_Be_Updated_From_Key_Vault";
|
||||||
|
String sampleDatabaseName = "your_db"; // update me
|
||||||
|
|
||||||
|
// Main entry point
|
||||||
|
public static void main(String[] args) {
|
||||||
|
App app = new App();
|
||||||
|
app.runDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to run the demp app
|
||||||
|
public void runDemo()
|
||||||
|
{
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_key_vault.vault.azure.net/") // Update me
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
password = secret.getValue();
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Configure Hibernate logging to only log SEVERE errors
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger("org.hibernate");
|
||||||
|
java.util.logging.Logger.getLogger("org.hibernate").setLevel(java.util.logging.Level.SEVERE);
|
||||||
|
|
||||||
|
System.out.println("**Java CRUD sample with Hibernate and Azure SQL **\n");
|
||||||
|
try {
|
||||||
|
// We're creating the Hibernate configuration via code. An alternative is to use a 'hibernate.cfg.xml' file.
|
||||||
|
Configuration cfg = createHibernateConfiguration();
|
||||||
|
|
||||||
|
// We're mapping POJO classes to Tables via Hibernate Annotations. An alternative is to use Hibernate mapping xml files.
|
||||||
|
cfg.addAnnotatedClass(User.class);
|
||||||
|
cfg.addAnnotatedClass(Task.class);
|
||||||
|
|
||||||
|
System.out.println("added classes to config");
|
||||||
|
|
||||||
|
|
||||||
|
// Hibernate needs an existing database. We already have one created.
|
||||||
|
|
||||||
|
// Create the Hibernate SessionFactory and Session.
|
||||||
|
// This causes Hibernate to create Tables and Relationships in the database from our Annotated classes.
|
||||||
|
try (SessionFactory sessionFactory = cfg.buildSessionFactory();
|
||||||
|
Session session = sessionFactory.openSession()) {
|
||||||
|
|
||||||
|
System.out.println("Created database schema from Java classes.\n");
|
||||||
|
session.beginTransaction();
|
||||||
|
|
||||||
|
// Create demo: Create a User instance and save it to the database
|
||||||
|
User newUser = new User("Anna", "Shrestinian");
|
||||||
|
session.save(newUser);
|
||||||
|
System.out.println("Created User: " + newUser.toString());
|
||||||
|
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
|
||||||
|
Task newTask = new Task("Ship Helsinki", sdf.parse("04-01-2017"));
|
||||||
|
session.save(newTask);
|
||||||
|
System.out.println("Created Task: " + newTask.toString());
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
newTask.setUser(newUser);
|
||||||
|
session.save(newTask);
|
||||||
|
System.out.println("Assigned Task: '" + newTask.getTitle() + "' to user '" + newUser.getFullName() + "'\n");
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna'
|
||||||
|
System.out.println("Incomplete tasks assigned to 'Anna':");
|
||||||
|
String hqlQuery = "from Task where isComplete = false and user.firstName = :paramFirstName";
|
||||||
|
List<Task> incompleteTasks = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.setParameter("paramFirstName", "Anna")
|
||||||
|
.getResultList();
|
||||||
|
for(Task theTask : incompleteTasks) {
|
||||||
|
System.out.println(theTask.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
hqlQuery = "from Task";
|
||||||
|
Task taskToUpdate = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.getResultList()
|
||||||
|
.get(0); // get the first task
|
||||||
|
System.out.println("\nUpdating task: " + taskToUpdate.toString());
|
||||||
|
taskToUpdate.setDueDate(sdf.parse("06-30-2016"));
|
||||||
|
session.save(taskToUpdate);
|
||||||
|
System.out.println("dueDate changed: " + taskToUpdate.toString());
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
System.out.println("\nDeleting all tasks with a dueDate in 2016");
|
||||||
|
hqlQuery = "from Task where dueDate < :paramDate";
|
||||||
|
List<Task> tasksToDelete = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.setParameter("paramDate", sdf.parse("12-31-2016"))
|
||||||
|
.getResultList();
|
||||||
|
for(Task theTask : tasksToDelete) {
|
||||||
|
System.out.println("Deleting task:" + theTask.toString());
|
||||||
|
session.delete(theTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show tasks after the 'Delete' operation - there should be 0 tasks
|
||||||
|
System.out.println("\nTasks after delete:");
|
||||||
|
hqlQuery = "from Task";
|
||||||
|
List<Task> tasksAfterDelete = session.createQuery(hqlQuery, Task.class)
|
||||||
|
.getResultList();
|
||||||
|
if(tasksAfterDelete.isEmpty()) {
|
||||||
|
System.out.println("[None]");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(Task theTask : tasksAfterDelete) {
|
||||||
|
System.out.println(theTask.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
}
|
||||||
|
System.out.println("All done.");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Hibernate configuration via code instead of using a
|
||||||
|
// 'hibernate.cfg.xml' file.
|
||||||
|
private Configuration createHibernateConfiguration() {
|
||||||
|
String url = this.connectionUrl + ";databaseName=" + this.sampleDatabaseName;
|
||||||
|
Configuration cfg = new Configuration()
|
||||||
|
.setProperty("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
|
||||||
|
.setProperty("hibernate.connection.url", url)
|
||||||
|
.setProperty("hibernate.connection.username", this.userName)
|
||||||
|
.setProperty("hibernate.connection.password", this.password)
|
||||||
|
.setProperty("hibernate.connection.autocommit", "true")
|
||||||
|
.setProperty("hibernate.show_sql", "false");
|
||||||
|
|
||||||
|
// Tell Hibernate to use the 'SQL Server' dialect when dynamically
|
||||||
|
// generating SQL queries
|
||||||
|
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
|
||||||
|
|
||||||
|
// Tell Hibernate to show the generated T-SQL
|
||||||
|
cfg.setProperty("hibernate.show_sql", "false");
|
||||||
|
|
||||||
|
// This is ok during development, but not recommended in production
|
||||||
|
// See: http://stackoverflow.com/questions/221379/hibernate-hbm2ddl-auto-update-in-production
|
||||||
|
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "Tasks")
|
||||||
|
public class Task {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id", updatable = false, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
private String title;
|
||||||
|
private Boolean isComplete;
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date dueDate;
|
||||||
|
|
||||||
|
// Specify a Many:1 mapping between Task and User
|
||||||
|
@ManyToOne
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Task() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task(String title, Date dueDate) {
|
||||||
|
this.title = title;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
this.isComplete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task(String title, Date dueDate, User user) {
|
||||||
|
this.title = title;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
this.isComplete = false;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return this.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDueDate() {
|
||||||
|
return this.dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDueDate(Date dueDate) {
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
|
||||||
|
return "Task [id=" + this.id + ", title=" + this.title + ", dueDate=" + ft.format(this.dueDate)
|
||||||
|
+ ", isComplete=" + this.isComplete.toString() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "Users")
|
||||||
|
public class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id", updatable = false, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
// Specify a 1:Many mapping between User and Task via the "user" field in
|
||||||
|
// the "Tasks" class.
|
||||||
|
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
|
||||||
|
private List<Task> tasks = new ArrayList<Task>();
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String firstName, String lastName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return this.firstName + " " + this.lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTasks(List<Task> tasks) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User [id=" + this.id + ", name=" + this.getFullName() + "]";
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlHibernateSample</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>AzureSqlHibernateSample</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- add the JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- add Hibernate -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>5.2.3.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.javassist</groupId>
|
||||||
|
<artifactId>javassist</artifactId>
|
||||||
|
<version>3.23.1-GA</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Add Key Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server_name.database.windows.net;databaseName=your_database_name;user=your_user;password=your_password";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load Azure SQL JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Done.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
System.out.print("Creating sample table with data, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
String sql = new StringBuilder().append("CREATE TABLE Employees ( ")
|
||||||
|
.append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ")
|
||||||
|
.append(" Location NVARCHAR(50) ").append("); ")
|
||||||
|
.append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ")
|
||||||
|
.append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
System.out.print("Inserting a new row into table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);")
|
||||||
|
.toString();
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, "Jake");
|
||||||
|
statement.setString(2, "United States");
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToUpdate);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "DELETE FROM Employees WHERE Name = ?;";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToDelete);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
System.out.print("Reading data from table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
try (Statement statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
System.out.println(
|
||||||
|
resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close();
|
||||||
|
System.out.println("All done.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)){
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Table cleaned up.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
package com.sqlsamples;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
|
||||||
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClient;
|
||||||
|
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
|
||||||
|
import com.azure.security.keyvault.secrets.SecretClientBuilder;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations.");
|
||||||
|
|
||||||
|
// Get the key vault secret
|
||||||
|
//
|
||||||
|
System.out.println("Fetching Secret from Key Vault.");
|
||||||
|
SecretClient secretClient = new SecretClientBuilder()
|
||||||
|
.vaultUrl("https://your_keyvault_name.vault.azure.net/")
|
||||||
|
.credential(new DefaultAzureCredentialBuilder().build())
|
||||||
|
.buildClient();
|
||||||
|
KeyVaultSecret secret = secretClient.getSecret("AppSecret");
|
||||||
|
System.out.println("Secret Fetched.");
|
||||||
|
|
||||||
|
// Update the connection information below
|
||||||
|
String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load Azure SQL JDBC driver and establish connection.
|
||||||
|
System.out.print("Connecting to Azure SQL ... ");
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
|
||||||
|
System.out.println("Done.");
|
||||||
|
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Done.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Table and insert some sample data
|
||||||
|
System.out.print("Creating sample table with data, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
String sql = new StringBuilder().append("CREATE TABLE Employees ( ")
|
||||||
|
.append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ")
|
||||||
|
.append(" Location NVARCHAR(50) ").append("); ")
|
||||||
|
.append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ")
|
||||||
|
.append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString();
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
System.out.println("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT demo
|
||||||
|
System.out.print("Inserting a new row into table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);")
|
||||||
|
.toString();
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, "Jake");
|
||||||
|
statement.setString(2, "United States");
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) inserted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE demo
|
||||||
|
String userToUpdate = "Nikita";
|
||||||
|
System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToUpdate);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE demo
|
||||||
|
String userToDelete = "Jared";
|
||||||
|
System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "DELETE FROM Employees WHERE Name = ?;";
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, userToDelete);
|
||||||
|
int rowsAffected = statement.executeUpdate();
|
||||||
|
System.out.println(rowsAffected + " row(s) deleted");
|
||||||
|
}
|
||||||
|
|
||||||
|
// READ demo
|
||||||
|
System.out.print("Reading data from table, press ENTER to continue...");
|
||||||
|
System.in.read();
|
||||||
|
sql = "SELECT Id, Name, Location FROM Employees;";
|
||||||
|
try (Statement statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = statement.executeQuery(sql)) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
System.out.println(
|
||||||
|
resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close();
|
||||||
|
System.out.println("All done.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
|
||||||
|
try (Connection connection = DriverManager.getConnection(connectionUrl)){
|
||||||
|
// Delete the Employees table if it exists
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("Drop table if exists Employees");
|
||||||
|
System.out.println("Table cleaned up.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.sqlsamples</groupId>
|
||||||
|
<artifactId>AzureSqlSample</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<name>AzureSqlSample</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.microsoft.sqlserver</groupId>
|
||||||
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
|
<version>7.0.0.jre8</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-secrets</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-security-keyvault-keys</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.azure</groupId>
|
||||||
|
<artifactId>azure-identity</artifactId>
|
||||||
|
<version>1.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [Java on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/windows/az) to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Developing applications with NodeJs and Azure SQL
|
||||||
|
|
||||||
|
Pick a platform below to get started:
|
||||||
|
* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based)
|
||||||
|
* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows)
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var uuid = require('node-uuid');
|
||||||
|
var async = require('async');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
var password;
|
||||||
|
var conn;
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
password = secret.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetConnection(){
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: password // will be retrieved
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
encrypt: true,
|
||||||
|
trustServerCertificate: true,
|
||||||
|
database: 'your_database' // update me
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
conn = new Connection(config);
|
||||||
|
conn.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec(sql) {
|
||||||
|
var timerName = "QueryTime";
|
||||||
|
|
||||||
|
var request = new Request(sql, function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.on('doneProc', function(rowCount, more, rows) {
|
||||||
|
if(!more){
|
||||||
|
console.timeEnd(timerName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
console.log("Sum: " + column.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.time(timerName);
|
||||||
|
conn.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
await GetConnection();
|
||||||
|
|
||||||
|
console.log("Got connection");
|
||||||
|
|
||||||
|
conn.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
function(){
|
||||||
|
exec('SELECT SUM(Price) FROM Table_with_3M_rows');},
|
||||||
|
]);
|
||||||
|
}});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: 'your_password' // update me
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
trustServerCertificate: true,
|
||||||
|
encrypt: true,
|
||||||
|
database: 'your_database' // update me
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var connection = new Connection(config);
|
||||||
|
connection.connect();
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
}
|
||||||
|
});
|
||||||
+150
@@ -0,0 +1,150 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: 'your_password' // update me
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
encrypt: true,
|
||||||
|
database: 'your_database', // update me
|
||||||
|
trustServerCertificate: true,
|
||||||
|
encrypt: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var connection = new Connection(config);
|
||||||
|
connection.connect();
|
||||||
|
|
||||||
|
function Start(callback) {
|
||||||
|
console.log('Starting...');
|
||||||
|
callback(null, 'Jake', 'United States');
|
||||||
|
}
|
||||||
|
|
||||||
|
function Insert(name, location, callback) {
|
||||||
|
console.log("Inserting '" + name + "' into Table...");
|
||||||
|
|
||||||
|
request = new Request(
|
||||||
|
'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) inserted');
|
||||||
|
callback(null, 'Nikita', 'United States');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update(name, location, callback) {
|
||||||
|
console.log("Updating Location to '" + location + "' for '" + name + "'...");
|
||||||
|
|
||||||
|
// Update the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) updated');
|
||||||
|
callback(null, 'Jared');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Delete(name, callback) {
|
||||||
|
console.log("Deleting '" + name + "' from Table...");
|
||||||
|
|
||||||
|
// Delete the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'DELETE FROM TestSchema.Employees WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) deleted');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Read(callback) {
|
||||||
|
console.log('Reading rows from the Table...');
|
||||||
|
|
||||||
|
// Read all rows from table
|
||||||
|
request = new Request(
|
||||||
|
'SELECT Id, Name, Location FROM TestSchema.Employees;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) returned');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Print the rows read
|
||||||
|
var result = "";
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
if (column.value === null) {
|
||||||
|
console.log('NULL');
|
||||||
|
} else {
|
||||||
|
result += column.value + " ";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(result);
|
||||||
|
result = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Complete(err, result) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log("Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
Start,
|
||||||
|
Insert,
|
||||||
|
Update,
|
||||||
|
Delete,
|
||||||
|
Read
|
||||||
|
], Complete)
|
||||||
|
}
|
||||||
|
});
|
||||||
+193
@@ -0,0 +1,193 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
var async = require('async');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
var pwd;
|
||||||
|
var connection;
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
console.log("got default cred");
|
||||||
|
|
||||||
|
const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
pwd = secret.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetConnection(){
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: pwd // fetched from key vault
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
database: 'your_database', // update me
|
||||||
|
trustServerCertificate: true,
|
||||||
|
encrypt: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection = new Connection(config);
|
||||||
|
await connection.connect();
|
||||||
|
console.log("Connected");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start(callback) {
|
||||||
|
console.log('Starting...');
|
||||||
|
callback(null, 'Jake', 'United States');
|
||||||
|
}
|
||||||
|
|
||||||
|
function Insert(name, location, callback) {
|
||||||
|
console.log("Inserting '" + name + "' into Table...");
|
||||||
|
|
||||||
|
request = new Request(
|
||||||
|
'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) inserted');
|
||||||
|
callback(null, 'Nikita', 'United States');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update(name, location, callback) {
|
||||||
|
console.log("Updating Location to '" + location + "' for '" + name + "'...");
|
||||||
|
|
||||||
|
// Update the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) updated');
|
||||||
|
callback(null, 'Jared');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Delete(name, callback) {
|
||||||
|
console.log("Deleting '" + name + "' from Table...");
|
||||||
|
|
||||||
|
// Delete the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'DELETE FROM TestSchema.Employees WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) deleted');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Read(callback) {
|
||||||
|
console.log('Reading rows from the Table...');
|
||||||
|
|
||||||
|
// Read all rows from table
|
||||||
|
request = new Request(
|
||||||
|
'SELECT Id, Name, Location FROM TestSchema.Employees;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) returned');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Print the rows read
|
||||||
|
var result = "";
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
if (column.value === null) {
|
||||||
|
console.log('NULL');
|
||||||
|
} else {
|
||||||
|
result += column.value + " ";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(result);
|
||||||
|
result = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Complete(err, result) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
console.log("Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
console.log('Starting');
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
await GetConnection();
|
||||||
|
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
Start,
|
||||||
|
Insert,
|
||||||
|
Update,
|
||||||
|
Delete,
|
||||||
|
Read
|
||||||
|
], Complete);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
+147
@@ -0,0 +1,147 @@
|
|||||||
|
var Sequelize = require('sequelize');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
|
||||||
|
var userName = 'your_user'; // update me
|
||||||
|
var password = 'fetch_from_key_vault'; // fetched from key vault
|
||||||
|
var hostName = 'your_server.database.windows.net'; // update me
|
||||||
|
var sampleDbName = 'your_database'; //update me
|
||||||
|
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
console.log("got default cred");
|
||||||
|
|
||||||
|
const vaultName = process.env["KEY_VAULT_NAME"] || "your_key_vault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
console.log("connecting to vault: " + vaultName + " at: " + url);
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
password = secret.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: "+ error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
console.log('Starting');
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
|
||||||
|
// Initialize Sequelize to connect to sample DB
|
||||||
|
var sampleDb = new Sequelize(sampleDbName, userName, password, {
|
||||||
|
dialect: 'mssql',
|
||||||
|
host: hostName,
|
||||||
|
port: 1433, // Default port
|
||||||
|
logging: false, // disable logging; default: console.log,
|
||||||
|
encrypt: true,
|
||||||
|
|
||||||
|
dialectOptions: {
|
||||||
|
requestTimeout: 30000 // timeout = 30 seconds
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the 'User' model
|
||||||
|
var User = sampleDb.define('user', {
|
||||||
|
firstName: Sequelize.STRING,
|
||||||
|
lastName: Sequelize.STRING
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the 'Task' model
|
||||||
|
var Task = sampleDb.define('task', {
|
||||||
|
title: Sequelize.STRING,
|
||||||
|
dueDate: Sequelize.DATE,
|
||||||
|
isComplete: Sequelize.BOOLEAN
|
||||||
|
});
|
||||||
|
|
||||||
|
// Model a 1:Many relationship between User and Task
|
||||||
|
User.hasMany(Task);
|
||||||
|
|
||||||
|
console.log('**Node CRUD sample with Sequelize and MSSQL **');
|
||||||
|
|
||||||
|
// Tell Sequelize to DROP and CREATE tables and relationships in the database
|
||||||
|
sampleDb.sync({force: true})
|
||||||
|
.then(function() {
|
||||||
|
console.log('\nCreated database schema from model.');
|
||||||
|
|
||||||
|
// Create demo: Create a User instance and save it to the database
|
||||||
|
User.create({firstName: 'Anna', lastName: 'Shrestinian'})
|
||||||
|
.then(function(user) {
|
||||||
|
console.log('\nCreated User:', user.get({ plain: true}));
|
||||||
|
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
Task.create({
|
||||||
|
title: 'Ship Helsinki', dueDate: new Date(2017,04,01), isComplete: false
|
||||||
|
})
|
||||||
|
.then(function(task) {
|
||||||
|
console.log('\nCreated Task:', task.get({ plain: true}));
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
user.setTasks([task])
|
||||||
|
.then(function() {
|
||||||
|
console.log('\nAssigned task \''
|
||||||
|
+ task.title
|
||||||
|
+ '\' to user ' + user.firstName
|
||||||
|
+ ' ' + user.lastName);
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna''
|
||||||
|
User.findAll({
|
||||||
|
where: { firstName: 'Anna'},
|
||||||
|
include: [{
|
||||||
|
model: Task,
|
||||||
|
where: { isComplete: false }
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
.then(function(users) {
|
||||||
|
console.log('\nIncomplete tasks assigned to Anna:\n',
|
||||||
|
JSON.stringify(users));
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
Task.findByPk(1).then(function(task) {
|
||||||
|
console.log('\nUpdating task:',
|
||||||
|
task.title + ' ' + task.dueDate);
|
||||||
|
task.update({
|
||||||
|
dueDate: new Date(2016,06,30)
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
console.log('dueDate changed:',
|
||||||
|
task.title + ' ' + task.dueDate);
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
console.log('\nDeleting all tasks with with a dueDate in 2016');
|
||||||
|
Task.destroy({
|
||||||
|
where: { dueDate: {[Sequelize.Op.lte]: new Date(2016,12,31)}},
|
||||||
|
}).then(function() { // delete this line and the below, and corresponding closing braces and see what happens.
|
||||||
|
Task.findAll()
|
||||||
|
.then(function(tasks) {
|
||||||
|
console.log('Tasks in database after delete:',
|
||||||
|
JSON.stringify(tasks));
|
||||||
|
console.log('\nAll done!');
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [NodeJs tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var uuid = require('node-uuid');
|
||||||
|
var async = require('async');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
var password;
|
||||||
|
var conn;
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
console.log("connecting to vault: " + vaultName + " at: " + url);
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
password = secret.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetConnection(){
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: password // will be retrieved
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
encrypt: true,
|
||||||
|
trustServerCertificate: true,
|
||||||
|
database: 'your_database' // update me
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
conn = new Connection(config);
|
||||||
|
conn.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec(sql) {
|
||||||
|
var timerName = "QueryTime";
|
||||||
|
|
||||||
|
var request = new Request(sql, function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.on('doneProc', function(rowCount, more, rows) {
|
||||||
|
if(!more){
|
||||||
|
console.timeEnd(timerName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
console.log("Sum: " + column.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.time(timerName);
|
||||||
|
conn.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
await GetConnection();
|
||||||
|
|
||||||
|
console.log("Got connection");
|
||||||
|
|
||||||
|
conn.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
function(){
|
||||||
|
exec('SELECT SUM(Price) FROM Table_with_3M_rows');},
|
||||||
|
]);
|
||||||
|
}});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: 'your_password' // update me
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
database: 'your_database', // update me
|
||||||
|
trustServerCertificate: true,
|
||||||
|
encrypt: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var connection = new Connection(config);
|
||||||
|
connection.connect();
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
}
|
||||||
|
});
|
||||||
+147
@@ -0,0 +1,147 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net',
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user',
|
||||||
|
password: 'your_password'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
database: 'your_database',
|
||||||
|
trustServerCertificate: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var connection = new Connection(config);
|
||||||
|
connection.connect();
|
||||||
|
|
||||||
|
function Start(callback) {
|
||||||
|
console.log('Starting...');
|
||||||
|
callback(null, 'Jake', 'United States');
|
||||||
|
}
|
||||||
|
|
||||||
|
function Insert(name, location, callback) {
|
||||||
|
console.log("Inserting '" + name + "' into Table...");
|
||||||
|
|
||||||
|
request = new Request(
|
||||||
|
'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) inserted');
|
||||||
|
callback(null, 'Nikita', 'United States');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update(name, location, callback) {
|
||||||
|
console.log("Updating Location to '" + location + "' for '" + name + "'...");
|
||||||
|
|
||||||
|
// Update the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) updated');
|
||||||
|
callback(null, 'Jared');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Delete(name, callback) {
|
||||||
|
console.log("Deleting '" + name + "' from Table...");
|
||||||
|
|
||||||
|
// Delete the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'DELETE FROM TestSchema.Employees WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) deleted');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Read(callback) {
|
||||||
|
console.log('Reading rows from the Table...');
|
||||||
|
|
||||||
|
// Read all rows from table
|
||||||
|
request = new Request(
|
||||||
|
'SELECT Id, Name, Location FROM TestSchema.Employees;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) returned');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Print the rows read
|
||||||
|
var result = "";
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
if (column.value === null) {
|
||||||
|
console.log('NULL');
|
||||||
|
} else {
|
||||||
|
result += column.value + " ";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(result);
|
||||||
|
result = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Complete(err, result) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log("Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
Start,
|
||||||
|
Insert,
|
||||||
|
Update,
|
||||||
|
Delete,
|
||||||
|
Read
|
||||||
|
], Complete)
|
||||||
|
}
|
||||||
|
});
|
||||||
+192
@@ -0,0 +1,192 @@
|
|||||||
|
var Connection = require('tedious').Connection;
|
||||||
|
var Request = require('tedious').Request;
|
||||||
|
var TYPES = require('tedious').TYPES;
|
||||||
|
var async = require('async');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
var pwd;
|
||||||
|
var connection;
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
console.log("got default cred");
|
||||||
|
|
||||||
|
const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
pwd = secret.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetConnection(){
|
||||||
|
|
||||||
|
// Create connection to database
|
||||||
|
var config = {
|
||||||
|
server: 'your_server.database.windows.net', // update me
|
||||||
|
authentication: {
|
||||||
|
type: 'default',
|
||||||
|
options: {
|
||||||
|
userName: 'your_user', // update me
|
||||||
|
password: pwd // fetched from key vault
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
database: 'your_database', // update me
|
||||||
|
trustServerCertificate: true,
|
||||||
|
encrypt: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection = new Connection(config);
|
||||||
|
await connection.connect();
|
||||||
|
console.log("Connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start(callback) {
|
||||||
|
console.log('Starting...');
|
||||||
|
callback(null, 'Jake', 'United States');
|
||||||
|
}
|
||||||
|
|
||||||
|
function Insert(name, location, callback) {
|
||||||
|
console.log("Inserting '" + name + "' into Table...");
|
||||||
|
|
||||||
|
request = new Request(
|
||||||
|
'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) inserted');
|
||||||
|
callback(null, 'Nikita', 'United States');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update(name, location, callback) {
|
||||||
|
console.log("Updating Location to '" + location + "' for '" + name + "'...");
|
||||||
|
|
||||||
|
// Update the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) updated');
|
||||||
|
callback(null, 'Jared');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
request.addParameter('Location', TYPES.NVarChar, location);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Delete(name, callback) {
|
||||||
|
console.log("Deleting '" + name + "' from Table...");
|
||||||
|
|
||||||
|
// Delete the employee record requested
|
||||||
|
request = new Request(
|
||||||
|
'DELETE FROM TestSchema.Employees WHERE Name = @Name;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) deleted');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.addParameter('Name', TYPES.NVarChar, name);
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Read(callback) {
|
||||||
|
console.log('Reading rows from the Table...');
|
||||||
|
|
||||||
|
// Read all rows from table
|
||||||
|
request = new Request(
|
||||||
|
'SELECT Id, Name, Location FROM TestSchema.Employees;',
|
||||||
|
function(err, rowCount, rows) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(rowCount + ' row(s) returned');
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Print the rows read
|
||||||
|
var result = "";
|
||||||
|
request.on('row', function(columns) {
|
||||||
|
columns.forEach(function(column) {
|
||||||
|
if (column.value === null) {
|
||||||
|
console.log('NULL');
|
||||||
|
} else {
|
||||||
|
result += column.value + " ";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(result);
|
||||||
|
result = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute SQL statement
|
||||||
|
connection.execSql(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Complete(err, result) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
console.log("Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
console.log('Starting');
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
await GetConnection();
|
||||||
|
|
||||||
|
connection.on('connect', function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
// Execute all functions in the array serially
|
||||||
|
async.waterfall([
|
||||||
|
Start,
|
||||||
|
Insert,
|
||||||
|
Update,
|
||||||
|
Delete,
|
||||||
|
Read
|
||||||
|
], Complete);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
+147
@@ -0,0 +1,147 @@
|
|||||||
|
var Sequelize = require('sequelize');
|
||||||
|
const KeyVaultSecrets = require("@azure/keyvault-secrets");
|
||||||
|
const Identity = require("@azure/identity");
|
||||||
|
|
||||||
|
|
||||||
|
var userName = 'your_user'; // update me
|
||||||
|
var password = 'fetch_from_key_vault'; // fetched from key vault
|
||||||
|
var hostName = 'your_server.database.windows.net'; // update me
|
||||||
|
var sampleDbName = 'your_database'; //update me
|
||||||
|
|
||||||
|
|
||||||
|
async function GetSecret(){
|
||||||
|
console.log("Getting secret...");
|
||||||
|
// DefaultAzureCredential expects the following three environment variables:
|
||||||
|
// - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
|
||||||
|
// - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
|
||||||
|
// - AZURE_CLIENT_SECRET: The client secret for the registered application
|
||||||
|
const credential = new Identity.DefaultAzureCredential();
|
||||||
|
|
||||||
|
console.log("got default cred");
|
||||||
|
|
||||||
|
const vaultName = process.env["KEYVAULT_NAME"] || "your_key_vault_name";
|
||||||
|
const url = `https://${vaultName}.vault.azure.net`;
|
||||||
|
|
||||||
|
console.log("connecting to vault: " + vaultName + " at: " + url);
|
||||||
|
|
||||||
|
const client = new KeyVaultSecrets.SecretClient(url, credential);
|
||||||
|
|
||||||
|
try {
|
||||||
|
secret = await client.getSecret('AppSecret').then((secret) => {
|
||||||
|
password = secret.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log("Error connecting to key vault: "+ err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function Main() {
|
||||||
|
|
||||||
|
// Attempt to connect and execute queries if connection goes through
|
||||||
|
console.log('Starting');
|
||||||
|
|
||||||
|
await GetSecret();
|
||||||
|
|
||||||
|
// Initialize Sequelize to connect to sample DB
|
||||||
|
var sampleDb = new Sequelize(sampleDbName, userName, password, {
|
||||||
|
dialect: 'mssql',
|
||||||
|
host: hostName,
|
||||||
|
port: 1433, // Default port
|
||||||
|
logging: false, // disable logging; default: console.log,
|
||||||
|
encrypt: true,
|
||||||
|
|
||||||
|
dialectOptions: {
|
||||||
|
requestTimeout: 30000 // timeout = 30 seconds
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the 'User' model
|
||||||
|
var User = sampleDb.define('user', {
|
||||||
|
firstName: Sequelize.STRING,
|
||||||
|
lastName: Sequelize.STRING
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the 'Task' model
|
||||||
|
var Task = sampleDb.define('task', {
|
||||||
|
title: Sequelize.STRING,
|
||||||
|
dueDate: Sequelize.DATE,
|
||||||
|
isComplete: Sequelize.BOOLEAN
|
||||||
|
});
|
||||||
|
|
||||||
|
// Model a 1:Many relationship between User and Task
|
||||||
|
User.hasMany(Task);
|
||||||
|
|
||||||
|
console.log('**Node CRUD sample with Sequelize and MSSQL **');
|
||||||
|
|
||||||
|
// Tell Sequelize to DROP and CREATE tables and relationships in the database
|
||||||
|
sampleDb.sync({force: true})
|
||||||
|
.then(function() {
|
||||||
|
console.log('\nCreated database schema from model.');
|
||||||
|
|
||||||
|
// Create demo: Create a User instance and save it to the database
|
||||||
|
User.create({firstName: 'Anna', lastName: 'Shrestinian'})
|
||||||
|
.then(function(user) {
|
||||||
|
console.log('\nCreated User:', user.get({ plain: true}));
|
||||||
|
|
||||||
|
// Create demo: Create a Task instance and save it to the database
|
||||||
|
Task.create({
|
||||||
|
title: 'Ship Helsinki', dueDate: new Date(2017,04,01), isComplete: false
|
||||||
|
})
|
||||||
|
.then(function(task) {
|
||||||
|
console.log('\nCreated Task:', task.get({ plain: true}));
|
||||||
|
|
||||||
|
// Association demo: Assign task to user
|
||||||
|
user.setTasks([task])
|
||||||
|
.then(function() {
|
||||||
|
console.log('\nAssigned task \''
|
||||||
|
+ task.title
|
||||||
|
+ '\' to user ' + user.firstName
|
||||||
|
+ ' ' + user.lastName);
|
||||||
|
|
||||||
|
// Read demo: find incomplete tasks assigned to user 'Anna''
|
||||||
|
User.findAll({
|
||||||
|
where: { firstName: 'Anna'},
|
||||||
|
include: [{
|
||||||
|
model: Task,
|
||||||
|
where: { isComplete: false }
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
.then(function(users) {
|
||||||
|
console.log('\nIncomplete tasks assigned to Anna:\n',
|
||||||
|
JSON.stringify(users));
|
||||||
|
|
||||||
|
// Update demo: change the 'dueDate' of a task
|
||||||
|
Task.findByPk(1).then(function(task) {
|
||||||
|
console.log('\nUpdating task:',
|
||||||
|
task.title + ' ' + task.dueDate);
|
||||||
|
task.update({
|
||||||
|
dueDate: new Date(2016,06,30)
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
console.log('dueDate changed:',
|
||||||
|
task.title + ' ' + task.dueDate);
|
||||||
|
|
||||||
|
// Delete demo: delete all tasks with a dueDate in 2016
|
||||||
|
console.log('\nDeleting all tasks with with a dueDate in 2016');
|
||||||
|
Task.destroy({
|
||||||
|
where: { dueDate: {[Sequelize.Op.lte]: new Date(2016,12,31)}},
|
||||||
|
}).then(function() { // delete this line and the below, and corresponding closing braces and see what happens.
|
||||||
|
Task.findAll()
|
||||||
|
.then(function(tasks) {
|
||||||
|
console.log('Tasks in database after delete:',
|
||||||
|
JSON.stringify(tasks));
|
||||||
|
console.log('\nAll done!');
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Main();
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [NodeJs on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/node/windows/az) to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Developing applications with PHP and Azure SQL
|
||||||
|
|
||||||
|
Pick a platform below to get started:
|
||||||
|
* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based)
|
||||||
|
* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows)
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
$time_start = microtime(true);
|
||||||
|
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
|
||||||
|
//Read Query
|
||||||
|
$tsql= "SELECT SUM(Price) as sum FROM Table_with_3M_rows";
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql);
|
||||||
|
echo ("Sum: ");
|
||||||
|
if ($getResults == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
|
||||||
|
echo ($row['sum'] . PHP_EOL);
|
||||||
|
|
||||||
|
}
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
function FormatErrors( $errors )
|
||||||
|
{
|
||||||
|
/* Display errors. */
|
||||||
|
echo "Error information: ";
|
||||||
|
|
||||||
|
foreach ( $errors as $error )
|
||||||
|
{
|
||||||
|
echo "SQLSTATE: ".$error['SQLSTATE']."";
|
||||||
|
echo "Code: ".$error['code']."";
|
||||||
|
echo "Message: ".$error['message']."";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$time_end = microtime(true);
|
||||||
|
$execution_time = round((($time_end - $time_start)*1000),2);
|
||||||
|
echo 'QueryTime: '.$execution_time.' ms';
|
||||||
|
|
||||||
|
?>
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
if($conn)
|
||||||
|
echo "Connected!"
|
||||||
|
?>
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
|
||||||
|
//Insert Query
|
||||||
|
echo ("Inserting a new row into table" . PHP_EOL);
|
||||||
|
$tsql= "INSERT INTO TestSchema.Employees (Name, Location) VALUES (?,?);";
|
||||||
|
$params = array('Jake','United States');
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) inserted: " . PHP_EOL);
|
||||||
|
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
//Update Query
|
||||||
|
|
||||||
|
$userToUpdate = 'Nikita';
|
||||||
|
$tsql= "UPDATE TestSchema.Employees SET Location = ? WHERE Name = ?";
|
||||||
|
$params = array('Sweden', $userToUpdate);
|
||||||
|
echo("Updating Location for user " . $userToUpdate . PHP_EOL);
|
||||||
|
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) updated: " . PHP_EOL);
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
//Delete Query
|
||||||
|
$userToDelete = 'Jared';
|
||||||
|
$tsql= "DELETE FROM TestSchema.Employees WHERE Name = ?";
|
||||||
|
$params = array($userToDelete);
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
echo("Deleting user " . $userToDelete . PHP_EOL);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) deleted: " . PHP_EOL);
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
|
||||||
|
//Read Query
|
||||||
|
$tsql= "SELECT Id, Name, Location FROM TestSchema.Employees;";
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql);
|
||||||
|
echo ("Reading data from table" . PHP_EOL);
|
||||||
|
if ($getResults == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
|
||||||
|
echo ($row['Id'] . " " . $row['Name'] . " " . $row['Location'] . PHP_EOL);
|
||||||
|
|
||||||
|
}
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
function FormatErrors( $errors )
|
||||||
|
{
|
||||||
|
/* Display errors. */
|
||||||
|
echo "Error information: ";
|
||||||
|
|
||||||
|
foreach ( $errors as $error )
|
||||||
|
{
|
||||||
|
echo "SQLSTATE: ".$error['SQLSTATE']."";
|
||||||
|
echo "Code: ".$error['code']."";
|
||||||
|
echo "Message: ".$error['message']."";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [PHP tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
$time_start = microtime(true);
|
||||||
|
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
|
||||||
|
//Read Query
|
||||||
|
$tsql= "SELECT SUM(Price) as sum FROM Table_with_3M_rows";
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql);
|
||||||
|
echo ("Sum: ");
|
||||||
|
if ($getResults == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
|
||||||
|
echo ($row['sum'] . PHP_EOL);
|
||||||
|
|
||||||
|
}
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
function FormatErrors( $errors )
|
||||||
|
{
|
||||||
|
/* Display errors. */
|
||||||
|
echo "Error information: ";
|
||||||
|
|
||||||
|
foreach ( $errors as $error )
|
||||||
|
{
|
||||||
|
echo "SQLSTATE: ".$error['SQLSTATE']."";
|
||||||
|
echo "Code: ".$error['code']."";
|
||||||
|
echo "Message: ".$error['message']."";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$time_end = microtime(true);
|
||||||
|
$execution_time = round((($time_end - $time_start)*1000),2);
|
||||||
|
echo 'QueryTime: '.$execution_time.' ms';
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
if($conn)
|
||||||
|
echo "Connected!"
|
||||||
|
?>
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
$serverName = "your_server.database.windows.net";
|
||||||
|
$connectionOptions = array(
|
||||||
|
"Database" => "your_database",
|
||||||
|
"Uid" => "your_user",
|
||||||
|
"PWD" => "your_password"
|
||||||
|
);
|
||||||
|
|
||||||
|
//Establishes the connection
|
||||||
|
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
||||||
|
|
||||||
|
//Insert Query
|
||||||
|
echo ("Inserting a new row into table" . PHP_EOL);
|
||||||
|
$tsql= "INSERT INTO TestSchema.Employees (Name, Location) VALUES (?,?);";
|
||||||
|
$params = array('Jake','United States');
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) inserted: " . PHP_EOL);
|
||||||
|
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
//Update Query
|
||||||
|
|
||||||
|
$userToUpdate = 'Nikita';
|
||||||
|
$tsql= "UPDATE TestSchema.Employees SET Location = ? WHERE Name = ?";
|
||||||
|
$params = array('Sweden', $userToUpdate);
|
||||||
|
echo("Updating Location for user " . $userToUpdate . PHP_EOL);
|
||||||
|
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) updated: " . PHP_EOL);
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
//Delete Query
|
||||||
|
$userToDelete = 'Jared';
|
||||||
|
$tsql= "DELETE FROM TestSchema.Employees WHERE Name = ?";
|
||||||
|
$params = array($userToDelete);
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql, $params);
|
||||||
|
echo("Deleting user " . $userToDelete . PHP_EOL);
|
||||||
|
$rowsAffected = sqlsrv_rows_affected($getResults);
|
||||||
|
if ($getResults == FALSE or $rowsAffected == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
echo ($rowsAffected. " row(s) deleted: " . PHP_EOL);
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
|
||||||
|
//Read Query
|
||||||
|
$tsql= "SELECT Id, Name, Location FROM TestSchema.Employees;";
|
||||||
|
$getResults= sqlsrv_query($conn, $tsql);
|
||||||
|
echo ("Reading data from table" . PHP_EOL);
|
||||||
|
if ($getResults == FALSE)
|
||||||
|
die(FormatErrors(sqlsrv_errors()));
|
||||||
|
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
|
||||||
|
echo ($row['Id'] . " " . $row['Name'] . " " . $row['Location'] . PHP_EOL);
|
||||||
|
}
|
||||||
|
sqlsrv_free_stmt($getResults);
|
||||||
|
|
||||||
|
function FormatErrors( $errors )
|
||||||
|
{
|
||||||
|
/* Display errors. */
|
||||||
|
echo "Error information: ";
|
||||||
|
|
||||||
|
foreach ( $errors as $error )
|
||||||
|
{
|
||||||
|
echo "SQLSTATE: ".$error['SQLSTATE']."";
|
||||||
|
echo "Code: ".$error['code']."";
|
||||||
|
echo "Message: ".$error['message']."";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [PHP on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/windows/az) to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Developing applications with Python and Azure SQL
|
||||||
|
|
||||||
|
Pick a platform below to get started:
|
||||||
|
* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based)
|
||||||
|
* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows)
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
import pyodbc
|
||||||
|
import datetime
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
|
||||||
|
|
||||||
|
from azure.identity import DefaultAzureCredential
|
||||||
|
from azure.keyvault.secrets import SecretClient
|
||||||
|
|
||||||
|
credential = DefaultAzureCredential()
|
||||||
|
|
||||||
|
secret_client = SecretClient(vault_url="https://<your_key_vault_name>.vault.azure.net", credential=credential)
|
||||||
|
|
||||||
|
# NOTE: please replace the ("<your-secret-name>") with the name of the secret in your vault
|
||||||
|
secret = secret_client.get_secret("AppSecret")
|
||||||
|
|
||||||
|
password = secret.value
|
||||||
|
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
tsql = "SELECT SUM(Price) as sum FROM Table_with_3M_rows"
|
||||||
|
a = datetime.datetime.now()
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
b = datetime.datetime.now()
|
||||||
|
c = b - a
|
||||||
|
for row in cursor:
|
||||||
|
print ('Sum:', str(row[0]))
|
||||||
|
print ('QueryTime:', c.microseconds, 'ms')
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
import pyodbc
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
password = 'your_password'
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
|
||||||
|
print ('Inserting a new row into table')
|
||||||
|
#Insert Query
|
||||||
|
tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);"
|
||||||
|
with cursor.execute(tsql,'Jake','United States'):
|
||||||
|
print ('Successfully Inserted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Update Query
|
||||||
|
print ('Updating Location for Nikita')
|
||||||
|
tsql = "UPDATE Employees SET Location = ? WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Sweden','Nikita'):
|
||||||
|
print ('Successfully Updated!')
|
||||||
|
|
||||||
|
|
||||||
|
#Delete Query
|
||||||
|
print ('Deleting user Jared')
|
||||||
|
tsql = "DELETE FROM Employees WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Jared'):
|
||||||
|
print ('Successfully Deleted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Select Query
|
||||||
|
print ('Reading data from table')
|
||||||
|
tsql = "SELECT Name, Location FROM Employees;"
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
row = cursor.fetchone()
|
||||||
|
while row:
|
||||||
|
print (str(row[0]) + " " + str(row[1]))
|
||||||
|
row = cursor.fetchone()
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
import pyodbc
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
|
||||||
|
from azure.identity import DefaultAzureCredential
|
||||||
|
from azure.keyvault.secrets import SecretClient
|
||||||
|
|
||||||
|
credential = DefaultAzureCredential()
|
||||||
|
|
||||||
|
secret_client = SecretClient(vault_url="https://<your_keyvault_name>.vault.azure.net", credential=credential)
|
||||||
|
|
||||||
|
# NOTE: please replace the ("<your-secret-name>") with the name of the secret in your vault
|
||||||
|
secret = secret_client.get_secret("AppSecret")
|
||||||
|
|
||||||
|
password = secret.value
|
||||||
|
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
|
||||||
|
|
||||||
|
print ('Inserting a new row into table')
|
||||||
|
#Insert Query
|
||||||
|
tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);"
|
||||||
|
with cursor.execute(tsql,'Jake','United States'):
|
||||||
|
print ('Successfully Inserted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Update Query
|
||||||
|
print ('Updating Location for Nikita')
|
||||||
|
tsql = "UPDATE Employees SET Location = ? WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Sweden','Nikita'):
|
||||||
|
print ('Successfully Updated!')
|
||||||
|
|
||||||
|
|
||||||
|
#Delete Query
|
||||||
|
print ('Deleting user Jared')
|
||||||
|
tsql = "DELETE FROM Employees WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Jared'):
|
||||||
|
print ('Successfully Deleted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Select Query
|
||||||
|
print ('Reading data from table')
|
||||||
|
tsql = "SELECT Name, Location FROM Employees;"
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
row = cursor.fetchone()
|
||||||
|
while row:
|
||||||
|
print (str(row[0]) + " " + str(row[1]))
|
||||||
|
row = cursor.fetchone()
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [Python tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
import pyodbc
|
||||||
|
import datetime
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
|
||||||
|
|
||||||
|
from azure.identity import DefaultAzureCredential
|
||||||
|
from azure.keyvault.secrets import SecretClient
|
||||||
|
|
||||||
|
credential = DefaultAzureCredential()
|
||||||
|
|
||||||
|
secret_client = SecretClient(vault_url="https://<your_key_vault_name>.vault.azure.net", credential=credential)
|
||||||
|
|
||||||
|
# NOTE: please replace the ("<your-secret-name>") with the name of the secret in your vault
|
||||||
|
secret = secret_client.get_secret("AppSecret")
|
||||||
|
|
||||||
|
password = secret.value
|
||||||
|
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
tsql = "SELECT SUM(Price) as sum FROM Table_with_3M_rows"
|
||||||
|
a = datetime.datetime.now()
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
b = datetime.datetime.now()
|
||||||
|
c = b - a
|
||||||
|
for row in cursor:
|
||||||
|
print ('Sum:', str(row[0]))
|
||||||
|
print ('QueryTime:', c.microseconds, 'ms')
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import pyodbc
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
password = 'your_password'
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
|
||||||
|
print ('Inserting a new row into table')
|
||||||
|
#Insert Query
|
||||||
|
tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);"
|
||||||
|
with cursor.execute(tsql,'Jake','United States'):
|
||||||
|
print ('Successfully Inserted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Update Query
|
||||||
|
print ('Updating Location for Nikita')
|
||||||
|
tsql = "UPDATE Employees SET Location = ? WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Sweden','Nikita'):
|
||||||
|
print ('Successfully Updated!')
|
||||||
|
|
||||||
|
|
||||||
|
#Delete Query
|
||||||
|
print ('Deleting user Jared')
|
||||||
|
tsql = "DELETE FROM Employees WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Jared'):
|
||||||
|
print ('Successfully Deleted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Select Query
|
||||||
|
print ('Reading data from table')
|
||||||
|
tsql = "SELECT Name, Location FROM Employees;"
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
row = cursor.fetchone()
|
||||||
|
while row:
|
||||||
|
print (str(row[0]) + " " + str(row[1]))
|
||||||
|
row = cursor.fetchone()
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
import pyodbc
|
||||||
|
server = 'your_server.database.windows.net'
|
||||||
|
database = 'your_database'
|
||||||
|
username = 'your_user'
|
||||||
|
|
||||||
|
from azure.identity import DefaultAzureCredential
|
||||||
|
from azure.keyvault.secrets import SecretClient
|
||||||
|
|
||||||
|
credential = DefaultAzureCredential()
|
||||||
|
|
||||||
|
secret_client = SecretClient(vault_url="https://<your_keyvault_name>.vault.azure.net", credential=credential)
|
||||||
|
|
||||||
|
# NOTE: please replace the ("<your-secret-name>") with the name of the secret in your vault
|
||||||
|
secret = secret_client.get_secret("AppSecret")
|
||||||
|
|
||||||
|
password = secret.value
|
||||||
|
|
||||||
|
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
|
||||||
|
cursor = cnxn.cursor()
|
||||||
|
|
||||||
|
|
||||||
|
print ('Inserting a new row into table')
|
||||||
|
#Insert Query
|
||||||
|
tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);"
|
||||||
|
with cursor.execute(tsql,'Jake','United States'):
|
||||||
|
print ('Successfully Inserted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Update Query
|
||||||
|
print ('Updating Location for Nikita')
|
||||||
|
tsql = "UPDATE Employees SET Location = ? WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Sweden','Nikita'):
|
||||||
|
print ('Successfully Updated!')
|
||||||
|
|
||||||
|
|
||||||
|
#Delete Query
|
||||||
|
print ('Deleting user Jared')
|
||||||
|
tsql = "DELETE FROM Employees WHERE Name = ?"
|
||||||
|
with cursor.execute(tsql,'Jared'):
|
||||||
|
print ('Successfully Deleted!')
|
||||||
|
|
||||||
|
|
||||||
|
#Select Query
|
||||||
|
print ('Reading data from table')
|
||||||
|
tsql = "SELECT Name, Location FROM Employees;"
|
||||||
|
with cursor.execute(tsql):
|
||||||
|
row = cursor.fetchone()
|
||||||
|
while row:
|
||||||
|
print (str(row[0]) + " " + str(row[1]))
|
||||||
|
row = cursor.fetchone()
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
## Sample details
|
||||||
|
|
||||||
|
Please visit the [Python on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/windows/az) to run through the sample in full with more detail.
|
||||||
|
|
||||||
|
<a name=disclaimers></a>
|
||||||
|
|
||||||
|
The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them.
|
||||||
|
## Related Links
|
||||||
|
|
||||||
|
For more information, see these articles:
|
||||||
|
* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
require 'tiny_tds'
|
||||||
|
@client = TinyTds::Client.new username: 'your_user@your_server', password: 'your_password',
|
||||||
|
dataserver: 'your_server.database.windows.net', database: 'your_database', azure: true, timeout: 600
|
||||||
|
|
||||||
|
|
||||||
|
# Calculate time difference in milliseconds
|
||||||
|
def time_diff_milli(start, finish)
|
||||||
|
((finish - start) * 1000).floor
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(sql)
|
||||||
|
@client.execute(sql).do
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensure the table doesn't already exist.
|
||||||
|
puts "Drop the table if it exists"
|
||||||
|
execute("Drop table if exists Table_with_3M_rows")
|
||||||
|
|
||||||
|
# Insert 3 million rows into the table 'Table_with_3M_rows'
|
||||||
|
puts "Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait."
|
||||||
|
execute("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))
|
||||||
|
SELECT TOP(3000000)
|
||||||
|
ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId
|
||||||
|
,a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId
|
||||||
|
,a.a * 10 AS Price
|
||||||
|
,CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName
|
||||||
|
INTO Table_with_3M_rows
|
||||||
|
FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;")
|
||||||
|
|
||||||
|
# Execute query without columnstore index
|
||||||
|
t1 = Time.now
|
||||||
|
execute("SELECT SUM(Price) as sum FROM Table_with_3M_rows")
|
||||||
|
t2 = Time.now
|
||||||
|
elapsedTimeWithoutIndex = time_diff_milli t1, t2
|
||||||
|
puts "Query time without columnstore index: #{elapsedTimeWithoutIndex}ms"
|
||||||
|
|
||||||
|
# Create columnnstore index on table 'Table_with_3M_rows'
|
||||||
|
puts("Adding a columnstore index to table 'Table_with_3M_rows'")
|
||||||
|
execute("CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;")
|
||||||
|
|
||||||
|
# Execute the same query with columnstore index
|
||||||
|
t3 = Time.now
|
||||||
|
execute("SELECT SUM(Price) as sum FROM Table_with_3M_rows")
|
||||||
|
t4 = Time.now
|
||||||
|
elapsedTimeWithIndex = time_diff_milli t3, t4
|
||||||
|
puts "Query time WITH columnstore index: #{elapsedTimeWithIndex}ms"
|
||||||
|
|
||||||
|
# Calculate performance improvement with columnstore index
|
||||||
|
perf_improvement = (elapsedTimeWithoutIndex / elapsedTimeWithIndex).floor
|
||||||
|
puts "Performance improvement with columnstore index: #{perf_improvement}x!"
|
||||||
|
|
||||||
|
@client.close
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
require 'active_record'
|
||||||
|
require 'tiny_tds'
|
||||||
|
require 'activerecord-sqlserver-adapter'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
|
ActiveRecord::Base.establish_connection(
|
||||||
|
:adapter=> "sqlserver",
|
||||||
|
:host => "localhost",
|
||||||
|
:username => "sa",
|
||||||
|
:password => "your_password"
|
||||||
|
)
|
||||||
|
|
||||||
|
#Create new database SampleDB
|
||||||
|
puts "Drop and create new database 'SampleDB'"
|
||||||
|
ActiveRecord::Base.connection.drop_database('SampleDB') rescue nil
|
||||||
|
ActiveRecord::Base.connection.create_database('SampleDB')
|
||||||
|
ActiveRecord::Base.connection.use_database('SampleDB')
|
||||||
|
|
||||||
|
#Create a new table called Tasks
|
||||||
|
ActiveRecord::Schema.define do
|
||||||
|
create_table :tasks, force: true do |t|
|
||||||
|
t.string :taskname
|
||||||
|
t.string :user
|
||||||
|
t.date :duedate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Task < ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
#Create new tasks and users
|
||||||
|
Task.create!(taskname:'Install SQL Server 2017 on Windows', user:'Andrea', duedate: '2017-07-01')
|
||||||
|
Task.create!(taskname:'Upgrade from SQL Server 2014 to 2017', user:'Meet', duedate: '2017-07-01')
|
||||||
|
Task.create!(taskname:'Write new SQL Server content', user:'Luis', duedate: '2017-07-01')
|
||||||
|
pp "Created new tasks:"
|
||||||
|
pp Task.all
|
||||||
|
|
||||||
|
#Update due date for specific task
|
||||||
|
task_to_update = Task.where(taskname: 'Install SQL Server 2017 on Windows').where(user: 'Andrea').first
|
||||||
|
puts "Updating the following task:"
|
||||||
|
pp task_to_update
|
||||||
|
task_to_update.update_attribute(:duedate, '2017-07-31')
|
||||||
|
puts "Due date changed:"
|
||||||
|
pp task_to_update
|
||||||
|
|
||||||
|
#Destroy all tasks for specific user
|
||||||
|
tasks_to_delete = Task.where(user: 'Meet').first
|
||||||
|
puts "Deleting all tasks for user:"
|
||||||
|
pp tasks_to_delete
|
||||||
|
tasks_to_delete.destroy!
|
||||||
|
|
||||||
|
#Read all tasks
|
||||||
|
puts "Printing all tasks:"
|
||||||
|
pp Task.all
|
||||||
|
|
||||||
|
ActiveRecord::Base.connection.close
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
require 'tiny_tds'
|
||||||
|
@client = TinyTds::Client.new username: 'your_user@your_server', password: 'your_password',
|
||||||
|
dataserver: 'your_server.database.windows.net', database: 'your_database', azure: true
|
||||||
|
|
||||||
|
puts 'Connecting to Azure SQL'
|
||||||
|
|
||||||
|
if @client.active? == true then puts 'Done' end
|
||||||
|
|
||||||
|
@client.close
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
require 'tiny_tds'
|
||||||
|
@client = TinyTds::Client.new username: 'sa', password: 'your_password',
|
||||||
|
host: 'localhost', port: 1433
|
||||||
|
puts 'Connecting to SQL Server'
|
||||||
|
|
||||||
|
if @client.active? == true then puts 'Done' end
|
||||||
|
|
||||||
|
def execute(sql)
|
||||||
|
result = @client.execute(sql)
|
||||||
|
result.each
|
||||||
|
if result.affected_rows > 0 then puts "#{result.affected_rows} row(s) affected" end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create database SampleDB
|
||||||
|
puts "Dropping and creating database 'SampleDB'"
|
||||||
|
execute("DROP DATABASE IF EXISTS [SampleDB]; CREATE DATABASE [SampleDB];")
|
||||||
|
|
||||||
|
# Create sample table with data
|
||||||
|
puts "Creating sample table with data"
|
||||||
|
execute("USE SampleDB; CREATE TABLE Employees (Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
|
||||||
|
Name NVARCHAR(50), Location NVARCHAR(50))
|
||||||
|
INSERT INTO Employees (Name, Location) VALUES (N'Jared', N'Australia'),
|
||||||
|
(N'Nikita', N'India'), (N'Tom', N'Germany')")
|
||||||
|
|
||||||
|
# Insert new employee
|
||||||
|
puts "Inserting new employee Jake into Employees table"
|
||||||
|
execute("INSERT INTO Employees (Name, Location) VALUES (N'Jake', N'United States')")
|
||||||
|
|
||||||
|
# Update location for employee
|
||||||
|
puts "Updating Location for Nikita"
|
||||||
|
execute("UPDATE Employees SET Location = N'United States' WHERE NAME = N'Nikita'")
|
||||||
|
|
||||||
|
# Delete employee
|
||||||
|
puts "Deleting employee Jared"
|
||||||
|
execute("DELETE FROM Employees WHERE NAME = N'Jared'")
|
||||||
|
|
||||||
|
# Read all employees
|
||||||
|
puts "Reading data from table"
|
||||||
|
@client.execute("SELECT * FROM Employees").each do |row|
|
||||||
|
puts row
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "All done."
|
||||||
|
|
||||||
|
@client.close
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Developing applications with Ruby and Azure SQL
|
||||||
|
|
||||||
|
|
||||||
|
Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/)
|
||||||
Reference in New Issue
Block a user