소스 제어의 저장 프로 시저 / DB 스키마
선택한 소스 제어 시스템에서 저장 프로 시저와 데이터베이스 스키마를 추적하고 있습니까?
변경 (테이블 추가, 저장된 프로 시저 업데이트) 할 때 변경 사항을 소스 제어로 가져 오는 방법은 무엇입니까?
우리는 직장에서 SQL Server를 사용하고 버전 관리를 위해 darcs를 사용하기 시작했지만 일반적인 전략과 편리한 도구에 대해 궁금합니다.
편집 : 와우, 모든 훌륭한 제안에 감사드립니다! 하나 이상의 "수락 된 답변"을 선택할 수 있으면 좋겠습니다!
모든 것을 스크립팅하기로 선택했으며 여기에는 모든 저장 프로 시저 및 스키마 변경이 포함됩니다. wysiwyg 도구가 없으며 멋진 '동기화'프로그램이 필요하지 않습니다.
스키마 변경은 간단합니다. 모든 스키마 및 데이터 변경을 포함하여 해당 버전에 대한 단일 파일을 만들고 유지 관리하기 만하면됩니다. 이것은 버전 x에서 x + 1 로의 변환 스크립트가됩니다. 그런 다음 프로덕션 백업에 대해 실행하고 '일일 빌드'에 통합하여 오류없이 작동하는지 확인할 수 있습니다. 나중에 작성된 SQL이 손상 될 수 있으므로 이미 작성된 스키마 / 데이터 로딩 SQL을 변경하거나 삭제하지 않는 것이 중요합니다.
-- change #1234
ALTER TABLE asdf ADD COLUMN MyNewID INT
GO
-- change #5678
ALTER TABLE asdf DROP COLUMN SomeOtherID
GO
저장 프로 시저의 경우 sproc 당 단일 파일을 선택하고 drop / create 양식을 사용합니다. 모든 저장 프로시 저는 배포시 다시 생성됩니다. 단점은 소스 제어 외부에서 변경이 수행되면 변경 내용이 손실된다는 것입니다. 동시에 모든 코드에 해당되지만 DBA는이를 인식해야합니다. 이렇게하면 업그레이드에서 변경 사항이 손실되기 때문에 팀 외부의 사람들이 저장 프로 시저를 비웃는 것을 막을 수 있습니다.
SQL Server를 사용하는 경우 구문은 다음과 같습니다.
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[usp_MyProc]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [usp_MyProc]
GO
CREATE PROCEDURE [usp_MyProc]
(
@UserID INT
)
AS
SET NOCOUNT ON
-- stored procedure logic.
SET NOCOUNT OFF
GO
남은 유일한 일은 모든 개별 파일을 수집하고 전체 업데이트 세트 (단일 스크립트)로 새 파일을 만드는 유틸리티 프로그램을 작성하는 것입니다. 먼저 스키마 변경 사항을 추가 한 다음 디렉터리 구조를 반복하고 모든 저장 프로 시저 파일을 포함하여이를 수행합니다.
모든 것을 스크립팅하는 것의 장점으로 SQL을 읽고 쓰는 데 훨씬 더 능숙해질 것입니다. 이 전체 프로세스를 더 정교하게 만들 수도 있지만 이것은 특별한 소프트웨어없이 모든 SQL을 소스 제어하는 방법의 기본 형식입니다.
부록 : Rick은 DROP / CREATE를 사용하여 저장 프로 시저에 대한 권한을 잃게된다는 말이 맞습니다. 따라서 특정 권한을 다시 활성화하려면 다른 스크립트를 작성해야 할 수도 있습니다. 이 권한 스크립트는 마지막으로 실행됩니다. 우리의 경험은 ALTER verses DROP / CREATE 의미론에서 더 많은 문제를 발견했습니다. YMMV
Visual Studio에서 "데이터베이스 프로젝트"를 만들어 sQL 코드를 작성 및 관리하고 나머지 솔루션과 함께 프로젝트를 버전 제어하에 유지합니다.
마지막 작업에서 사용한 솔루션은 소스 제어에 추가 될 때 스크립트에 번호를 매기는 것이 었습니다.
01. CreateUserTable.sql
02.PopulateUserTable
03.AlterUserTable.sql
04.CreateOrderTable.sql
아이디어는 우리가 항상 스크립트를 실행하는 순서를 알고 있었고 스크립트 # 1을 수정하려고 할 때 발생할 수있는 데이터 무결성 문제를 관리 할 필요가 없다는 것이 었습니다 (추정 적으로 # 2의 INSERT가 실패 할 수 있음).
SQL Server에서 삭제 / 만들기 스크립트에서 명심해야 할 한 가지는 개체 수준 권한이 손실된다는 것입니다. 대신 이러한 권한을 유지하는 ALTER 스크립트를 사용하도록 표준을 변경했습니다.
개체를 삭제하면 sp_depends에서 사용하는 종속성 레코드가 삭제되고 개체를 만들면 해당 개체에 대한 종속성 만 생성된다는 사실과 같은 몇 가지 다른주의 사항이 있습니다. 따라서보기를 삭제 / 만들면 sp_depends는 해당보기를 참조하는 개체를 더 이상 인식하지 못합니다.
이야기의 도덕, ALTER 스크립트를 사용하십시오.
나는 Robert Paulson의 관행에 동의하고 찬성합니다. 그것은 당신이 그러한 관행을 고수 할 책임과 규율을 가진 개발 팀을 통제하고 있다고 가정합니다.
이를 내 팀에 "강제"하기 위해 당사 솔루션 은 데이터베이스 전문가 용 Visual Studio Team Edition의 데이터베이스 프로젝트를 하나 이상 유지 합니다. 솔루션의 다른 프로젝트와 마찬가지로 데이터베이스 프로젝트는 버전 관리를받습니다. 데이터베이스의 모든 것을 유지 관리 할 수있는 덩어리로 나누는 것이 자연스러운 개발 프로세스가되어 팀을 "훈련"합니다.
물론 Visual Studio 프로젝트이기 때문에 거의 완벽하지는 않습니다. 당신을 실망 시키거나 혼란스럽게 할 수있는 많은 단점이 있습니다. 작업을 수행하기 전에 프로젝트가 어떻게 작동하는지 이해하는 데 약간의 시간이 필요합니다. 예는 다음과 같습니다.
- CSV 파일에서 데이터 배포 .
- 빌드 유형에 따라 테스트 데이터를 선택적으로 배포합니다 .
- .NET Framework에 포함 된 특정 유형의 CLR 어셈블리가있는 데이터베이스와 비교할 때 Visual Studio가 충돌합니다 .
- 다른 인증 체계를 구현하는 테스트 / 프로덕션 데이터베이스 (SQL 사용자와 Active Directory 사용자)를 구분할 수단이 없습니다.
하지만 데이터베이스 개체의 버전을 관리하지 않는 팀에게는 좋은 시작입니다. 다른 유명한 대안은 물론 Red Gate의 SQL Server 제품군으로 ,이를 사용하는 대부분의 사람들은 Microsoft 제품보다 우수하다고 생각합니다.
저장 프로 시저를 포함하여 데이터베이스를 자동으로 설정하는 스크립트를 작성해야한다고 생각합니다. 그런 다음이 스크립트를 소스 제어에 배치해야합니다.
내 경험에서 몇 가지 다른 관점. Oracle 세계에서는 모든 것이 "create"DDL 스크립트로 관리되었습니다. ahockley가 언급했듯이 각 개체에 대해 하나의 스크립트. 개체를 변경해야하는 경우 해당 DDL 스크립트가 수정됩니다. 원하는 환경에 현재 DB 빌드를 배포 할 수 있도록 모든 개체 스크립트를 호출하는 하나의 래퍼 스크립트가 있습니다. 이것은 메인 코어 생성을위한 것입니다.
분명히 라이브 애플리케이션에서는 새 열이 필요한 새 빌드를 푸시 할 때마다 테이블을 삭제하고 새로 만들지 않습니다. ALTER 스크립트를 수행하고 열을 추가합니다. 따라서 이러한 종류의 변경이 필요할 때마다 항상 두 가지를 수행해야합니다. 1) 변경 DDL을 작성하고 2) 코어를 업데이트하여 변경 사항을 반영하도록 DDL을 작성하십시오. 둘 다 소스 제어로 이동하지만 단일 변경 스크립트는 델타를 적용하는 데만 사용되기 때문에 일시적인 시점 변경에 가깝습니다.
ERWin과 같은 도구를 사용하여 모델을 업데이트하고 DDL을 앞으로 생성 할 수도 있지만 내가 아는 대부분의 DBA는 스크립트를 원하는 방식으로 정확하게 생성하는 모델링 도구를 신뢰하지 않습니다. ERWin을 사용하여 주기적으로 핵심 DDL 스크립트를 모델로 리버스 엔지니어링 할 수도 있지만 제대로 보이도록 만드는 데 많은 소란이 있습니다 (할 때마다).
Microsoft 세계에서도 비슷한 전략을 사용했지만 Red Gate 제품을 사용하여 스크립트와 델타를 관리했습니다. 여전히 스크립트를 소스 제어에 둡니다. 객체 당 하나의 스크립트 (테이블, sproc 등). 처음에 일부 DBA는 스크립트를 사용하는 대신 SQL Server GUI를 사용하여 개체를 관리하는 것을 선호했습니다. 그러나 이로 인해 기업이 성장함에 따라 일관되게 관리하기가 매우 어려웠습니다.
DDL이 소스 제어에있는 경우 빌드 도구 (일반적으로 개미)를 사용하여 배포 스크립트를 작성하는 것은 간단합니다.
이 작업을 수행하는 가장 쉽고 빠르고 안전한 방법은 총알을 물어 뜯고 RedGate의 SQL 소스 제어를 사용하는 것입니다. 몇 분 만에 스크립팅되고 저장소에 저장됩니다. RedGate가 제품을 손실 리더로 간주하여 더 널리 사용되기를 바랍니다.
위의 Robert Paulson과 유사하게 우리 조직은 데이터베이스를 소스 제어하에 유지합니다. 그러나 우리의 차이점은 우리가 가지고있는 스크립트의 수를 제한하려고한다는 것입니다.
새 프로젝트에는 정해진 절차가 있습니다. 버전 1의 스키마 생성 스크립트, 저장된 proc 생성 스크립트 및 가능한 초기 데이터로드 생성 스크립트가 있습니다. 모든 프록은 하나의 대용량 파일에 보관됩니다. Enterprise Library를 사용하는 경우 로깅을위한 생성 스크립트 사본이 포함됩니다. ASP.NET 애플리케이션 프레임 워크 (인증, 개인화 등)를 사용하는 ASP.NET 프로젝트 인 경우 해당 스크립트도 포함됩니다. (Microsoft의 도구에서 생성 한 다음 여러 사이트에서 복제 가능한 방식으로 작동 할 때까지 조정했습니다. 재미는 아니지만 귀중한 시간 투자입니다.)
우리는 우리가 좋아하는 proc을 찾기 위해 마법의 CTRL + F를 사용합니다. :) (SQL Management Studio에 VS와 같은 코드 탐색 기능이 있다면 좋겠습니다. 한숨!)
후속 버전의 경우 일반적으로 upgradeSchema, upgradeProc 및 / 또는 updateDate 스크립트가 있습니다. 스키마 업데이트의 경우 테이블을 최대한 변경하여 필요에 따라 새 테이블을 만듭니다. proc 업데이트의 경우 DROP 및 CREATE.
이 접근법으로 하나의 주름이 나타납니다. 데이터베이스를 생성하는 것은 쉽고 현재 DB 버전에서 새로운 데이터베이스를 쉽게 얻을 수 있습니다. 그러나 DB / schema / proc 변경 사항이 액세스에 사용되는 코드와 명확하게 동기화되도록 DAL 생성 (현재는 일반적으로 SubSonic으로 수행)에주의를 기울여야합니다. 그러나 빌드 경로에는 SubSonic DAL을 생성하는 배치 파일이 있으므로 DAL 코드를 체크 아웃하고 해당 배치 파일을 다시 실행 한 다음 스키마 및 / 또는 프로세스가 변경 될 때마다 다시 확인하는 것이 SOP입니다. (물론 이것은 소스 빌드를 트리거하고 적절한 DLL에 대한 공유 종속성을 업데이트합니다.)
과거의 경험에서 저는 제품의 각 릴리스에 대해 데이터베이스 변경 사항이 항상 스크립팅되어 작업중인 릴리스에 저장되도록 데이터베이스 변경 소스를 제어했습니다. 구축 프로세스는 각 "응용 프로그램"에 대한 현재 버전을 저장 한 데이터베이스의 테이블을 기반으로 데이터베이스를 현재 버전으로 자동으로 가져옵니다. 우리가 작성한 사용자 지정 .net 유틸리티 응용 프로그램은 데이터베이스의 현재 버전을 실행하고 확인한 다음 스크립트의 접두사 번호 순서대로 새로운 스크립트를 실행합니다. 그런 다음 모든 것이 정상인지 확인하기 위해 단위 테스트를 실행했습니다.
다음과 같이 소스 제어에 스크립트를 저장합니다 (아래 폴더 구조).
나는 테이블과 저장 프로 시저에 대한 현재 명명 규칙에 약간 녹슬었기 때문에 내 예제를 맨손으로 ...
[루트]
[응용 프로그램]
[버전]
[스크립트]
\ scripts
MyApplication \
1.2.1 \
001.MyTable.Create.sql
002.MyOtherTable.Create.sql
100.dbo.usp.MyTable.GetAllNewStuff.sql
애플리케이션 및 버전을 고려하는 버전 테이블을 사용하면 애플리케이션이 주간 프로덕션 백업을 복원하고 현재 버전 이후 데이터베이스에 대해 필요한 모든 스크립트를 실행합니다. .net을 사용함으로써 우리는 이것을 트랜잭션으로 쉽게 패키징 할 수 있었고 실패한 것이 있으면 롤백하고 이메일을 보내어 릴리스에 잘못된 스크립트가 있음을 알았습니다.
따라서 모든 개발자는 소스 제어에서이를 유지하여 조정 된 릴리스가 데이터베이스에 대해 실행하려는 모든 스크립트가 성공적으로 실행되도록합니다.
이것은 아마도 여러분이 찾고 있던 것보다 더 많은 정보 일 것입니다. 그러나 그것은 우리에게 매우 잘 작동했고 구조를 고려할 때 모든 개발자를 쉽게 참여시킬 수있었습니다.
출시일이 다가 오면 운영 팀은 출시 노트를 따르고 소스 제어에서 스크립트를 선택하고 야간 빌드 프로세스에서 사용한 .net 애플리케이션을 사용하여 데이터베이스에 대해 패키지를 실행하여 트랜잭션에서 스크립트를 자동으로 패키징했습니다. 뭔가 실패하면 자동으로 롤백되며 데이터베이스에 영향을주지 않습니다.
저장 프로시 저는 최상위에있는 drop / create 문이있는 경우 표준을 사용하여 sp 당 1 개의 파일을 얻습니다. 뷰와 함수는 자체 파일을 가져 오므로 버전을 만들고 재사용하기가 더 쉽습니다.
스키마는 모두 1 개의 스크립트로 시작하여 버전을 변경합니다.
이 모든 것은 다음과 같은 폴더 구조로 TFS (@ work 또는 VisualSVN Server @ home for personal stuff)에 연결된 Visual Studio 데이터베이스 프로젝트에 저장됩니다
.-프로젝트
-함수
-스키마
-저장 프로 시저
-뷰
우리 회사에서는 개별 코드 파일과 마찬가지로 모든 데이터베이스 항목을 소스 제어에 개별 스크립트로 저장하는 경향이 있습니다. 모든 업데이트는 먼저 데이터베이스에서 수행 된 다음 소스 코드 저장소로 마이그레이션되므로 변경 내역이 유지됩니다.
두 번째 단계로 모든 데이터베이스 변경 사항이 통합 데이터베이스로 마이그레이션됩니다. 이 통합 데이터베이스는 배포 후 프로덕션 데이터베이스의 모습을 정확하게 나타냅니다. 또한 현재 프로덕션 상태 (또는 마지막 배포)를 나타내는 QA 데이터베이스도 있습니다. 통합 데이터베이스에서 모든 변경이 이루어지면 스키마 비교 도구 (Red Gate의 SQL Server 용 SQL Diff)를 사용하여 모든 변경 사항을 한 데이터베이스에서 다른 데이터베이스로 마이그레이션하는 스크립트를 생성합니다.
설치 프로그램과 쉽게 통합 할 수있는 단일 스크립트를 생성하므로이 방법이 상당히 효과적이라는 것을 알았습니다. 우리가 자주 겪는 가장 큰 문제는 개발자가 변경 사항을 통합으로 마이그레이션하는 것을 잊는 것입니다.
저장 프로 시저를 소스 제어에 보관합니다.
모든 것을 스크립팅 (개체 생성 등)하고 해당 스크립트를 소스 제어에 저장합니다. 변경 사항은 어떻게 적용됩니까? 일이 수행되는 방식에 대한 표준 관행의 일부입니다. 테이블을 추가해야합니까? CREATE TABLE 스크립트를 작성하십시오. sproc을 업데이트 하시겠습니까? 저장 프로 시저 스크립트를 편집하십시오.
개체 당 하나의 스크립트를 선호합니다.
procs의 경우 스크립트 래퍼가있는 procs를 일반 파일에 작성하고 해당 파일의 변경 사항을 적용합니다. 올바르게 적용된 경우 해당 파일을 체크인 할 수 있으며 해당 파일에서도 복제 할 수 있습니다.
스키마 변경의 경우 변경 사항을 점진적으로 적용하려면 스크립트를 체크인해야 할 수 있습니다. 스크립트를 작성하고 적용한 다음 체크인합니다. 그런 다음 프로세스를 구축하여 각 스키마 스크립트를 직렬로 자동 적용 할 수 있습니다.
저장 프로 시저를 소스 제어에 보관합니다. 우리 (또는 적어도 내가)하는 방법은 내 프로젝트에 폴더를 추가하고 각 SP에 대한 파일을 추가 한 다음 코드를 수동으로 복사하여 붙여 넣는 것입니다. 따라서 SP를 변경할 때 소스 제어 파일을 수동으로 변경해야합니다.
사람들이이 작업을 자동으로 수행 할 수 있는지 듣고 싶습니다.
소스 제어에서 스키마와 저장 프로 시저를 유지하는 것이 좋습니다.
저장 프로 시저의 버전을 유지하면 문제가 있다고 판단 될 때 롤백 할 수 있습니다.
스키마는 의미에 따라 덜 분명한 대답입니다. 복제 환경 (prod / dev / user 등)을 위해 소스 제어에서 테이블을 정의하는 SQL을 유지하는 것은 매우 유용합니다.
우리는 현재 프로젝트에서 다른 접근 방식을 사용하고 있습니다. 소스 제어 아래에 db가 없지만 대신 데이터베이스 diff 도구를 사용하여 각 릴리스에 도달 할 때 변경 내용을 스크립팅했습니다.
지금까지 매우 잘 작동하고 있습니다.
애플리케이션과 관련된 모든 것을 SCM에 저장합니다. DB 스크립트는 일반적으로 자체 프로젝트에 저장되지만 디자인, 구현, 테스트, 커밋 등 다른 코드와 마찬가지로 처리됩니다.
작업을 실행하여 공식적인 디렉토리 구조로 스크립팅합니다.
다음은 작업을 수행하는 배치 파일에서 호출되는 VS2005 코드, 명령 줄 프로젝트입니다. 코드 끝의 app.config 키.
온라인에서 찾은 다른 코드를 기반으로합니다. 설정하는 데 약간의 고통이 있지만 일단 작동하면 잘 작동합니다.
Imports Microsoft.VisualStudio.SourceSafe.Interop
Imports System
Imports System.Configuration
Module Module1
Dim sourcesafeDataBase As String, sourcesafeUserName As String, sourcesafePassword As String, sourcesafeProjectName As String, fileFolderName As String
Sub Main()
If My.Application.CommandLineArgs.Count > 0 Then
GetSetup()
For Each thisOption As String In My.Application.CommandLineArgs
Select Case thisOption.ToUpper
Case "CHECKIN"
DoCheckIn()
Case "CHECKOUT"
DoCheckOut()
Case Else
DisplayUsage()
End Select
Next
Else
DisplayUsage()
End If
End Sub
Sub DisplayUsage()
Console.Write(System.Environment.NewLine + "Usage: SourceSafeUpdater option" + System.Environment.NewLine + _
"CheckIn - Check in ( and adds any new ) files in the directory specified in .config" + System.Environment.NewLine + _
"CheckOut - Check out all files in the directory specified in .config" + System.Environment.NewLine + System.Environment.NewLine)
End Sub
Sub AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_RECURSYES + VSSFlags.VSSFLAG_DELNO
Try
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Add(fileFolderName, "", Flags)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("already exists") > 0 Then
Console.Write(ex.Message)
End If
End Try
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckIn()
AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_UPDUPDATE + VSSFlags.VSSFLAG_FORCEDIRYES + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkin("", fileFolderName, Flags)
Dim File As String
For Each File In My.Computer.FileSystem.GetFiles(fileFolderName)
Try
Proj.Add(fileFolderName + File)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("access code") > 0 Then
Console.Write(ex.Message)
End If
End Try
Next
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckOut()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_REPREPLACE + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkout("", fileFolderName, Flags)
Proj = Nothing
db = Nothing
End Sub
Sub GetSetup()
sourcesafeDataBase = ConfigurationManager.AppSettings("sourcesafeDataBase")
sourcesafeUserName = ConfigurationManager.AppSettings("sourcesafeUserName")
sourcesafePassword = ConfigurationManager.AppSettings("sourcesafePassword")
sourcesafeProjectName = ConfigurationManager.AppSettings("sourcesafeProjectName")
fileFolderName = ConfigurationManager.AppSettings("fileFolderName")
End Sub
End Module
<add key="sourcesafeDataBase" value="C:\wherever\srcsafe.ini"/>
<add key="sourcesafeUserName" value="vssautomateuserid"/>
<add key="sourcesafePassword" value="pw"/>
<add key="sourcesafeProjectName" value="$/where/you/want/it"/>
<add key="fileFolderName" value="d:\yourdirstructure"/>
쉽고 기성품 솔루션을 찾고 있다면 Sql Historian 시스템은 백그라운드 프로세스를 사용하여 DDL 변경 사항을 TFS 또는 SVN에 자동으로 동기화하여 데이터베이스를 변경하는 모든 사람에게 투명합니다. 제 경험상 가장 큰 문제는 소스 제어에서 코드를 서버에서 변경된 내용으로 유지하는 것입니다. 왜냐하면 일반적으로 워크 플로를 변경하고 변경 사항을 확인하는 것을 기억하기 위해 사람 (개발자, 심지어!)에게 의존해야하기 때문입니다. 그들이 이미 서버에서 만든 후에. 기계에 부담을 주면 모든 사람의 삶이 더 쉬워집니다.
참고 URL : https://stackoverflow.com/questions/77172/stored-procedures-db-schema-in-source-control
'Program Club' 카테고리의 다른 글
| 이미지를 늘리지 않고 이미지의 너비와 높이를 설정하는 방법은 무엇입니까? (0) | 2020.11.09 |
|---|---|
| CSS : 표 열 사이의 테두리 만 (0) | 2020.11.09 |
| C #에서 속성 선언의 "new"키워드 (0) | 2020.11.08 |
| 특정 기능에 대해 ECMAscript 엄격 모드를 비활성화 할 수 있습니까? (0) | 2020.11.08 |
| 오류 : C 스택 사용량이 한계에 너무 가깝습니다. (0) | 2020.11.08 |