Azure SQL Database에 ASP.NET 애플리케이션 연결

완료됨

애플리케이션에서 Azure SQL Database 서비스 내의 데이터베이스에 연결하는 여러 가지 방법이 있습니다. .NET 앱의 경우 System.Data.SqlClient 라이브러리를 사용할 수 있습니다.

대학용 웹앱은 SQL 데이터베이스에 업로드된 데이터를 가져와서 표시해야 합니다. 이 단원에서는 웹앱에서 데이터베이스에 연결하고 System.Data.SqlClient 라이브러리를 사용하여 데이터를 처리하는 방법을 알아봅니다.

System.Data.SqlClient 라이브러리 개요

System.Data.SqlClient 라이브러리는 SQL Database의 클라우드 또는 온-프레미스에서 실행 중인 SQL Server 데이터베이스에 연결하는 데 사용할 수 있는 형식 및 메서드 컬렉션입니다. 이 라이브러리는 데이터 검색 및 유지 관리를 위해 일반화된 인터페이스를 제공합니다. System.Data.SqlClient 라이브러리를 사용하여 T-SQL(Transact-SQL) 명령 및 트랜잭션 작업을 실행하고 데이터를 검색할 수 있습니다. 이러한 작업을 매개 변수화하여 SQL 삽입 공격과 관련된 문제를 방지할 수 있습니다. 작업이 실패하면 System.Data.SqlClient 라이브러리는 특수화된 예외 및 오류 클래스를 통해 오류 정보를 제공합니다. 이러한 예외는 .NET 애플리케이션의 다른 예외 유형과 동일한 방식으로 처리합니다.

System.Data.SqlClient 라이브러리는 System.Data.SqlClient NuGet 패키지에서 사용할 수 있습니다.

단일 데이터베이스에 연결

SqlConnection 개체를 사용하여 데이터베이스 연결을 만듭니다. 데이터베이스의 이름과 위치를 지정하는 연결 문자열(connection string), 사용할 자격 증명, 기타 연결 관련 매개 변수를 제공합니다. 일반적인 단일 데이터베이스 연결 문자열은 다음과 같습니다.

Server=tcp:myserver.database.windows.net,1433;Initial Catalog=mydatabase;Persist Security Info=False;User ID=myusername;Password=mypassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

단일 데이터베이스 연결 문자열은 Azure Portal의 데이터베이스 연결 문자열 페이지에서 찾을 수 있습니다.

다음 코드 예제에서는 SqlConnection 개체를 만드는 방법을 보여 줍니다.

using System.Data.SqlClient;

...

string connectionString = "Server=tcp:myserver.database.windows.net,...";
SqlConnection con = new SqlConnection(connectionString);

연결을 열기 전에는 데이터베이스 연결이 설정되지 않습니다. 연결은 보통 T-SQL 명령 또는 쿼리를 실행하기 직전에 엽니다.

con.Open();

일부 데이터베이스는 한정된 개수의 동시 연결만 지원합니다. 따라서 명령 실행과 결과 검색을 마친 후에는 연결을 닫고 사용된 리소스를 모두 해제하는 것이 좋습니다.

con.Close();

또 다른 일반적인 방법은 using 문에서 연결을 만드는 것입니다. 이 방법을 사용할 경우 using 문이 완료되면 연결이 자동으로 닫힙니다. 하지만 Close 메서드를 명시적으로 호출할 수도 있습니다.

using (SqlConnection con = new SqlConnection(connectionString))
{
    // Open and Use the connection here
    con.Open();
    ...
}
// Connection is now closed

T-SQL 명령 또는 쿼리 정의

SqlCommand 개체를 생성하여 실행할 T-SQL 명령 또는 쿼리를 지정합니다. 다음 예제에서는 dbo.Orders 테이블에서 주어진 고객의 행을 제거하는 T-SQL DELETE 문을 보여 줍니다. 명령을 매개 변수화할 수 있습니다. 이 예제에서는 CustomerID 값으로 CustID라는 매개 변수를 사용합니다. SqlCommand 개체의 CommandType 속성을 Text로 설정하는 줄은 이 명령이 T-SQL 문임을 나타냅니다. T-SQL 문 대신 저장 프로시저를 실행할 수도 있습니다. 이 경우 CommandTypeStoredProcedure로 설정합니다.

SqlCommand deleteOrdersForCustomer = new SqlCommand("DELETE FROM Orders WHERE CustomerID = @custID", con);
deleteOrdersForCustomer.CommandType = CommandType.Text;
string customerID = <prompt the user for a customer to delete>;
deleteOrdersForCustomer.Parameters.Add(new SqlParameter("custID", customerID));

이 예제에서 SqlCommand 생성자의 마지막 매개 변수는 명령을 실행하는 데 사용되는 연결입니다.

다음 예제에서는 dbo.Customersdbo.Orders 테이블을 함께 조인하여 고객 이름 및 주문 목록을 생성하는 쿼리를 보여 줍니다.

SqlCommand queryCmd = new SqlCommand(
                    @"SELECT c.FirstName, c.LastName, o.OrderID
                      FROM Customers c JOIN Orders o
                      ON c.CustomerID = o.CustomerID", con);
queryCmd.CommandType = CommandType.Text;

명령 실행

SqlCommand 개체가 결과 집합을 반환하지 않는 T-SQL 문을 참조하는 경우 ExecuteNonQuery 메서드를 사용하여 명령을 실행합니다. 명령이 성공하면 작업의 영향을 받는 행의 개수가 반환됩니다. 다음 예제에서는 앞에 표시된 deleteOrdersForCustomer 명령을 실행하는 방법을 보여 줍니다.

int numDeleted = deleteOrdersForCustomer.ExecuteNonQuery();

명령을 실행하는 데 시간이 걸릴 것으로 예상되면, ExecuteNonQueryAsync 메서드를 사용하여 작업을 비동기적으로 수행할 수 있습니다.

쿼리 실행 및 데이터 가져오기

SqlCommand가 T-SQL SELECT 문을 포함하는 경우 ExecuteReader 메서드를 사용하여 실행합니다. 이 메서드는 결과를 반복하고 각 행을 차례로 처리하는 데 사용할 수 있는 SqlDataReader 개체를 반환합니다. Read 메서드를 사용하여 SqlReader 개체에서 데이터를 검색합니다. 이 메서드는 행을 찾으면 true를 반환하고, 읽을 행이 남아있지 않으면 false를 반환합니다. 행을 읽은 후에는 SqlReader 개체의 필드에서 행의 데이터를 사용할 수 있습니다. 각 필드는 원래 SELECT 문의 해당 열과 동일한 이름을 갖습니다. 하지만 각 필드의 데이터는 형식화되지 않은 object로 검색되기 때문에 적절한 형식으로 변환해야 사용할 수 있습니다. 다음 코드는 앞서 설명한 queryCmd 명령을 실행하여 데이터를 한 번에 한 행씩 가져오는 방법을 보여 줍니다.

SqlDataReader rdr = queryCmd.ExecuteReader();

// Read the data a row at a time
while (rdr.Read())
{
    string firstName = rdr["FirstName"].ToString();
    string lastName = rdr["LastName"].ToString();
    int orderID = Convert.ToInt32(rdr["OrderID"]);

    // Process the data
    ...
}

예외 및 오류 처리

데이터베이스를 사용할 때 여러 가지 이유로 예외와 오류가 발생할 수 있습니다. 예를 들어 더 이상 존재하지 않는 테이블에 액세스하려고 할 수 있습니다. T-SQL 오류는 SqlException 형식을 사용하여 catch할 수 있습니다.

데이터베이스의 다양한 이벤트 또는 문제는 예외를 트리거할 수 있습니다. SqlException 개체에는 SqlError 개체 컬렉션이 포함된 Errors 속성이 있습니다. 이러한 개체는 각 오류에 대한 세부 정보를 제공합니다. 다음 예제에서는 SqlException을 catch하고 포함된 오류를 처리하는 방법을 보여 줍니다.

...
using (SqlConnection con = new SqlConnection(connectionString))
{
    SqlCommand command = new SqlCommand("DELETE FROM ...", con);
    try
    {
        con.Open();
        command.ExecuteNonQuery();
    }
    catch (SqlException ex)
    {
        for (int i = 0; i < ex.Errors.Count; i++)
        {
            Console.WriteLine($"Index # {i} Error: {ex.Errors[i].ToString()}");
        }
    }
}