기술적 인 주제와 마찬가지로 Idealism, Pragmatism 또는 Ignorance를 기반으로 한 광범위한 의견이 있습니다. 커서를 사용하는 것이 괜찮은지 물어 보면 오히려 빨리 볼 수 있습니다 :).
나는 "비즈니스 논리"가 "데이터 논리"라고 부르는 것과는 별도로 실제 비즈니스 논리를 정확히 구성하는 것을 구분하는 시간이 상대적으로 거의없는 것처럼 보이기 때문에 "비즈니스 논리 없음"이라는 것이 가장 이상하다고 생각합니다. Data Logic은 RDMBS를 사용하여 효율적으로 데이터를 조작합니다.
필자는 좀 더 실용적인 접근법을 사용하여 실제로 수행중인 작업과 그 작업을 가장 효율적으로 수행하는 작업을 살펴 봅니다. 루프를 통해 proc 나 app 레이어에서 관련 레코드를 지정하는 특별한 경우에는, 한 줄 주석으로는 할 수 없었던 것을 얻지 못했을 때 앱 레이어에서 그런 일을하는 것은 어리석은 일이라고 생각합니다 그러나 반복 된 데이터베이스 호출을하려면 막대한 비용이 듭니다. 물론 루프 된 호출을 트랜잭션으로 랩핑하고 동일한 연결을 사용하면 비용이 절감 될 수 있지만 스토어드 프로 시저의 간단한 세트 기반 명령문처럼 효율적이지는 않습니다.
틀린 말은하지 마세요. 알고리즘은 앱 레이어에 있어야한다는 것에 동의하지만 일단 데이터를 유지해야한다면 DB에 전달하여 작업을 수행해야합니다. 다만 수행 응용 프로그램 코드에서
CREATE PROCEDURE dbo.Add_Password
(
@UserID INT,
@Password NVARCHAR(50),
@PasswordID INT OUTPUT = -1
)
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN;
INSERT INTO dbo.Passwords (UserID, [Password])
VALUES (@UserID, @Password);
SET @PasswordID = SCOPE_IDENTITY();
INSERT INTO dbo.PasswordAccess (UserID, PasswordID)
SELECT usr.UserID, @PasswordID
FROM dbo.Users usr
WHERE usr.UserType = 1; -- Assuming 1 = Admin
COMMIT TRAN;
END TRY
BEGIN CATCH
ROLLBACK TRAN;
THROW;
END CATCH;
: 예를 들어
, 당신의 Add_Password
시저 같은 것을 할 수
// Insert new password and assign access to all Admin-level Users (i.e. UserType = 1)
SqlCommand.ExecuteNonQuery();
모든 응용 프로그램 계층에서 이렇게 의미 "의 모든 점점 Admin "사용자 ID와 각각 AddAccess
을 호출 하시겠습니까? 그것은 비효율적 일뿐만 아니라 복잡하게 보입니다.
일반적으로 DB에서 과 같은 "데이터 로직"(예 : 위 예제와 같이)을 수행하려고 시도하지만은 "DB의 비즈니스 로직 없음"이라는 이상에 걸리지 않습니다. 당신은 DB에 그 중 일부를 넣는 것에서 진정으로 이익을 얻는 상황이 있다면 당신의 프로젝트가 어려움을 겪게합니다.DB 호출에서 어떤 일이 일어나고 있는지에 대한 앱 코드의 설명 (정보/세부 사항이 충분한 유용한 주석과 신비가 아닌 실제 아이디어를 전달하는 세부 정보)을 꼭 입력해야합니다.
편집 : 이러한 유형의 작업에 대한 완성도를 위해서
,이 새로운 무언가를 추가하는 시간이있다, 그러나 협회의 목록은 응용 프로그램 계층에서가 아니라 데이터베이스에 수집에 저장 . 다음 PasswordID
을 반환하는 AddPassword
저장 프로 시저를 호출하고 AddAccess
이 PasswordID
이고 한 번에 UserID
이 전달되는 Admins
컬렉션을 루프에서 사용하면됩니까? 대답은 여전히 "아니오"입니다. 이 경우 Admins
컬렉션을 순환하여 CSV 문자열 또는 특성 기반 XML 문서를 저장 프로 시저로 전달할 수 있습니다. 컬렉션에서 추출한 ID 목록이 커지면 (즉, 100,000 개가 넘는 항목) TVP (테이블 반환 매개 변수)가 더 효율적일 수 있지만 작은 목록의 경우 TVP 은 오버 엔지니어링 ()이 될 수 있습니다 분명히 각 상황에 가장 적합한 것을하십시오). 나는 이상적인 세계는 구성 형태의 일종의으로 비즈니스 로직의 대부분을 원하는 것이 믿는
CREATE PROCEDURE dbo.Add_Password
(
@UserID INT,
@Password NVARCHAR(50),
@AdminIDs VARCHAR(MAX), -- CSV list of UserIDs that are Admin/UserType = 1
@PasswordID INT OUTPUT = -1
)
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN;
INSERT INTO dbo.Passwords (UserID, [Password])
VALUES (@UserID, @Password);
SET @PasswordID = SCOPE_IDENTITY();
INSERT INTO dbo.PasswordAccess (UserID, PasswordID)
SELECT split.[Value], @PasswordID
FROM dbo.SqlClrOrXmlStringSplitter(@AdminIDs, ',') split;
COMMIT TRAN;
END TRY
BEGIN CATCH
ROLLBACK TRAN;
THROW;
END CATCH;
굉장한 답변, 고마워요. – binks
@binks : 언제든지 :). TRY/CATCH 및 트랜잭션 처리 기능이 있어야하므로 SQL을 약간 업데이트했습니다. 또한 EDIT 섹션을 추가하여보다 선명한 그림을 그려 낼 수 있습니다. Upvote? : D –
+1 이러한 상세한 대답을 위해, 누군가가 당신을 위해 당신의 문제를 해결하기 위해이 많은 시간을 보낸다면, 그 사람은 upvote를받을 자격이 있으며, 그것은 사람들이 질 높은 응답을 제공하도록 장려합니다. –