[SQL] 는 SQL Server의 기능에 값을 쉼표로 가득한 VARCHAR 구분 전달
SQL는 SQL Server의 기능에 값을 쉼표로 가득한 VARCHAR 구분 전달
나는 내가 IN 기능에 쉼표로 구분 된 값 가득 VARCHAR를 전달하고자하는 저장 프로 시저 SQL Server를 가지고있다. 예를 들면 :
DECLARE @Ids varchar(50);
SET @Ids = '1,2,3,5,4,6,7,98,234';
SELECT *
FROM sometable
WHERE tableid IN (@Ids);
이것은 물론 작동하지 않습니다. 나는 오류가 발생합니다 :
어떻게이 달성 (또는 상대적으로 비슷한) 동적 SQL을 구축에 의존하지 않고 할 수 있습니까?
해결법
-
==============================
1.루프는 문자열을 분할하는 기능을 사용하지 마십시오! 아무 루핑으로, 매우 빠른 문자열을 분할합니다 아래 내 기능!
루프는 문자열을 분할하는 기능을 사용하지 마십시오! 아무 루핑으로, 매우 빠른 문자열을 분할합니다 아래 내 기능!
내 기능을 사용하기 전에, 당신은, 당신은 단지 데이터베이스 당이 한 번 할 필요는 "도우미"테이블을 설정해야합니다 :
CREATE TABLE Numbers (Number int NOT NULL, CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] DECLARE @x int SET @x=0 WHILE @x<8000 BEGIN SET @x=@x+1 INSERT INTO Numbers VALUES (@x) END
루프를하지 않는 매우 빠른 당신의 문자열을 분할이 기능을 사용 :
CREATE FUNCTION [dbo].[FN_ListToTable] ( @SplitOn char(1) --REQUIRED, the character to split the @List string on ,@List varchar(8000) --REQUIRED, the list to split apart ) RETURNS @ParsedList table ( ListValue varchar(500) ) AS BEGIN /** Takes the given @List string and splits it apart based on the given @SplitOn character. A table is returned, one row per split item, with a column name "ListValue". This function workes for fixed or variable lenght items. Empty and null items will not be included in the results set. Returns a table, one row per item in the list, with a column name "ListValue" EXAMPLE: ---------- SELECT * FROM dbo.FN_ListToTable(',','1,12,123,1234,54321,6,A,*,|||,,,,B') returns: ListValue ----------- 1 12 123 1234 54321 6 A * ||| B (10 row(s) affected) **/ ---------------- --SINGLE QUERY-- --this will not return empty rows ---------------- INSERT INTO @ParsedList (ListValue) SELECT ListValue FROM (SELECT LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue FROM ( SELECT @SplitOn + @List + @SplitOn AS List2 ) AS dt INNER JOIN Numbers n ON n.Number < LEN(dt.List2) WHERE SUBSTRING(List2, number, 1) = @SplitOn ) dt2 WHERE ListValue IS NOT NULL AND ListValue!='' RETURN END --Function FN_ListToTable
당신이있는 테이블로이 기능을 사용할 수 있습니다 가입 :
SELECT Col1, COl2, Col3... FROM YourTable INNER JOIN FN_ListToTable(',',@YourString) s ON YourTable.ID = s.ListValue
여기 예입니다 :
Select * from sometable where tableid in(SELECT ListValue FROM dbo.FN_ListToTable(',',@Ids) s)
-
==============================
2.당신이 나 같은 게으른 있다면 물론, 당신은이 작업을 수행 할 수 있습니다 :
당신이 나 같은 게으른 있다면 물론, 당신은이 작업을 수행 할 수 있습니다 :
Declare @Ids varchar(50) Set @Ids = ',1,2,3,5,4,6,7,98,234,' Select * from sometable where Charindex(','+cast(tableid as varchar(8000))+',', @Ids) > 0
-
==============================
3.없음 표 없음 기능 없음 루프
없음 표 없음 기능 없음 루프
테이블에 목록을 구문 분석의 아이디어를 구축 우리의 DBA는 XML을 사용하여 제안했다.
Declare @Ids varchar(50) Set @Ids = ‘1,2,3,5,4,6,7,98,234’ DECLARE @XML XML SET @XML = CAST('<i>' + REPLACE(@Ids, ',', '</i><i>') + '</i>' AS XML) SELECT * FROM SomeTable INNER JOIN @XML.nodes('i') x(i) ON SomeTable .Id = x.i.value('.', 'VARCHAR(MAX)')
이들은 많은 간단, 생각, KM의 대답 @와 같은 성능을 갖고있는 것 같아요하지만.
-
==============================
4.당신은 테이블을 반환하는 함수를 만들 수 있습니다.
당신은 테이블을 반환하는 함수를 만들 수 있습니다.
당신의 문장은 같은 것 때문에
select * from someable join Splitfunction(@ids) as splits on sometable.id = splits.id
여기서 유사한 기능이다.
CREATE FUNCTION [dbo].[FUNC_SplitOrderIDs] ( @OrderList varchar(500) ) RETURNS @ParsedList table ( OrderID int ) AS BEGIN DECLARE @OrderID varchar(10), @Pos int SET @OrderList = LTRIM(RTRIM(@OrderList))+ ',' SET @Pos = CHARINDEX(',', @OrderList, 1) IF REPLACE(@OrderList, ',', '') <> '' BEGIN WHILE @Pos > 0 BEGIN SET @OrderID = LTRIM(RTRIM(LEFT(@OrderList, @Pos - 1))) IF @OrderID <> '' BEGIN INSERT INTO @ParsedList (OrderID) VALUES (CAST(@OrderID AS int)) --Use Appropriate conversion END SET @OrderList = RIGHT(@OrderList, LEN(@OrderList) - @Pos) SET @Pos = CHARINDEX(',', @OrderList, 1) END END RETURN END
-
==============================
5.그것은 매우 일반적인 질문입니다. 통조림 대답은, 몇 가지 좋은 기술 :
그것은 매우 일반적인 질문입니다. 통조림 대답은, 몇 가지 좋은 기술 :
http://www.sommarskog.se/arrays-in-sql-2005.html
-
==============================
6.이 완벽하게 작동합니다! 아래의 답변은 너무 복잡합니다. 동적으로이 보지 마십시오. 다음과 같이 저장 프로 시저를 설정합니다 :
이 완벽하게 작동합니다! 아래의 답변은 너무 복잡합니다. 동적으로이 보지 마십시오. 다음과 같이 저장 프로 시저를 설정합니다 :
(@id as varchar(50)) as Declare @query as nvarchar(max) set @query =' select * from table where id in('+@id+')' EXECUTE sp_executesql @query
-
==============================
7.동적 SQL을 사용하지 않고, 당신은 입력 변수를 가지고 임시 테이블에 데이터를 넣어 분할 기능을 사용하고 그 다음에 가입해야합니다.
동적 SQL을 사용하지 않고, 당신은 입력 변수를 가지고 임시 테이블에 데이터를 넣어 분할 기능을 사용하고 그 다음에 가입해야합니다.
-
==============================
8.나는이 등을 사용하는 것이 좋습니다 수 있습니다 :
나는이 등을 사용하는 것이 좋습니다 수 있습니다 :
DECLARE @Delim char(1) = ','; SET @Ids = @Ids + @Delim; WITH CTE(i, ls, id) AS ( SELECT 1, CHARINDEX(@Delim, @Ids, 1), SUBSTRING(@Ids, 1, CHARINDEX(@Delim, @Ids, 1) - 1) UNION ALL SELECT i + 1, CHARINDEX(@Delim, @Ids, ls + 1), SUBSTRING(@Ids, ls + 1, CHARINDEX(@Delim, @Ids, ls + 1) - CHARINDEX(@Delim, @Ids, ls) - 1) FROM CTE WHERE CHARINDEX(@Delim, @Ids, ls + 1) > 1 ) SELECT t.* FROM yourTable t INNER JOIN CTE c ON t.id = c.id;
-
==============================
9.덕분에, 당신의 기능을 위해 내가 IT를 사용 ........................ 이것은 나의 예입니다
덕분에, 당신의 기능을 위해 내가 IT를 사용 ........................ 이것은 나의 예입니다
**UPDATE [RD].[PurchaseOrderHeader] SET [DispatchCycleNumber] ='10' WHERE OrderNumber in(select * FROM XA.fn_SplitOrderIDs(@InvoiceNumberList))** CREATE FUNCTION [XA].[fn_SplitOrderIDs] ( @OrderList varchar(500) ) RETURNS @ParsedList table ( OrderID int ) AS BEGIN DECLARE @OrderID varchar(10), @Pos int SET @OrderList = LTRIM(RTRIM(@OrderList))+ ',' SET @Pos = CHARINDEX(',', @OrderList, 1) IF REPLACE(@OrderList, ',', '') <> '' BEGIN WHILE @Pos > 0 BEGIN SET @OrderID = LTRIM(RTRIM(LEFT(@OrderList, @Pos - 1))) IF @OrderID <> '' BEGIN INSERT INTO @ParsedList (OrderID) VALUES (CAST(@OrderID AS int)) --Use Appropriate conversion END SET @OrderList = RIGHT(@OrderList, LEN(@OrderList) - @Pos) SET @Pos = CHARINDEX(',', @OrderList, 1) END END RETURN END
-
==============================
10.당신은 SQL 서버 2008 이상, 사용 테이블 반환 매개 변수를 사용하는 경우; 예를 들어 :
당신은 SQL 서버 2008 이상, 사용 테이블 반환 매개 변수를 사용하는 경우; 예를 들어 :
CREATE PROCEDURE [dbo].[GetAccounts](@accountIds nvarchar) AS BEGIN SELECT * FROM accountsTable WHERE accountId IN (select * from @accountIds) END CREATE TYPE intListTableType AS TABLE (n int NOT NULL) DECLARE @tvp intListTableType -- inserts each id to one row in the tvp table INSERT @tvp(n) VALUES (16509),(16685),(46173),(42925),(46167),(5511) EXEC GetAccounts @tvp
-
==============================
11.파싱 쉼표 VARCHAR를 분리하고 다른 테이블과 결합 될 수있다 내부 테이블을 리턴하는 등 아래 테이블 생성 기능.
파싱 쉼표 VARCHAR를 분리하고 다른 테이블과 결합 될 수있다 내부 테이블을 리턴하는 등 아래 테이블 생성 기능.
CREATE FUNCTION [dbo].[fn_SplitList] ( @inString varchar(MAX) = '', @inDelimiter char(1) = ',' -- Keep the delimiter to 100 chars or less. Generally a delimiter will be 1-2 chars only. ) RETURNS @tbl_Return table ( Unit varchar(1000) COLLATE Latin1_General_BIN ) AS BEGIN INSERT INTO @tbl_Return SELECT DISTINCT LTRIM(RTRIM(piece.value('./text()[1]', 'varchar(1000)'))) COLLATE DATABASE_DEFAULT AS Unit FROM ( -- -- Replace any delimiters in the string with the "X" tag. -- SELECT CAST(('<X>' + REPLACE(s0.prsString, s0.prsSplitDelimit, '</X><X>') + '</X>') AS xml).query('.') AS units FROM ( -- -- Convert the string and delimiter into XML. -- SELECT (SELECT @inString FOR XML PATH('')) AS prsString, (SELECT @inDelimiter FOR XML PATH('')) AS prsSplitDelimit ) AS s0 ) AS s1 CROSS APPLY units.nodes('X') x(piece) RETURN END
================================================= 이제 위의 코드에서 테이블 함수를 만들어 소비 기능의 생성은 같은 서버에서뿐만 아니라 데이터베이스에서 사용할 수있는 데이터베이스에 한 번 활동이다.
DECLARE @Ids varchar(50); SET @Ids = '1,2,3,5,4,6,7,98,234'; SELECT * FROM sometable AS st INNER JOIN fn_SplitList(@ids, ',') AS sl ON sl.unit = st.tableid
-
==============================
12.난 아주 간단한 해결책은 다음이 될 수 있다고 생각 :
난 아주 간단한 해결책은 다음이 될 수 있다고 생각 :
DECLARE @Ids varchar(50); SET @Ids = '1,2,3,5,4,6,7,98,234'; SELECT * FROM sometable WHERE ','+@Ids+',' LIKE '%,'+CONVERT(VARCHAR(50),tableid)+',%';
-
==============================
13.나는 전에이 작업을 수행하는 방법을 보여주기 위해 저장 프로 시저를 작성했습니다. 당신은 기본적으로 문자열을 처리해야합니다. 나는 여기에 코드를 게시하려고하지만 형식이 모두 터져 있어요.
나는 전에이 작업을 수행하는 방법을 보여주기 위해 저장 프로 시저를 작성했습니다. 당신은 기본적으로 문자열을 처리해야합니다. 나는 여기에 코드를 게시하려고하지만 형식이 모두 터져 있어요.
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[uspSplitTextList]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1) DROP PROCEDURE [dbo].[uspSplitTextList] GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -- uspSplitTextList -- -- Description: -- splits a separated list of text items and returns the text items -- -- Arguments: -- @list_text - list of text items -- @Delimiter - delimiter -- -- Notes: -- 02/22/2006 - WSR : use DATALENGTH instead of LEN throughout because LEN doesn't count trailing blanks -- -- History: -- 02/22/2006 - WSR : revised algorithm to account for items crossing 8000 character boundary -- 09/18/2006 - WSR : added to this project -- CREATE PROCEDURE uspSplitTextList @list_text text, @Delimiter varchar(3) AS SET NOCOUNT ON DECLARE @InputLen integer -- input text length DECLARE @TextPos integer -- current position within input text DECLARE @Chunk varchar(8000) -- chunk within input text DECLARE @ChunkPos integer -- current position within chunk DECLARE @DelimPos integer -- position of delimiter DECLARE @ChunkLen integer -- chunk length DECLARE @DelimLen integer -- delimiter length DECLARE @ItemBegPos integer -- item starting position in text DECLARE @ItemOrder integer -- item order in list DECLARE @DelimChar varchar(1) -- first character of delimiter (simple delimiter) -- create table to hold list items -- actually their positions because we may want to scrub this list eliminating bad entries before substring is applied CREATE TABLE #list_items ( item_order integer, item_begpos integer, item_endpos integer ) -- process list IF @list_text IS NOT NULL BEGIN -- initialize SET @InputLen = DATALENGTH(@list_text) SET @TextPos = 1 SET @DelimChar = SUBSTRING(@Delimiter, 1, 1) SET @DelimLen = DATALENGTH(@Delimiter) SET @ItemBegPos = 1 SET @ItemOrder = 1 SET @ChunkLen = 1 -- cycle through input processing chunks WHILE @TextPos <= @InputLen AND @ChunkLen <> 0 BEGIN -- get current chunk SET @Chunk = SUBSTRING(@list_text, @TextPos, 8000) -- setup initial variable values SET @ChunkPos = 1 SET @ChunkLen = DATALENGTH(@Chunk) SET @DelimPos = CHARINDEX(@DelimChar, @Chunk, @ChunkPos) -- loop over the chunk, until the last delimiter WHILE @ChunkPos <= @ChunkLen AND @DelimPos <> 0 BEGIN -- see if this is a full delimiter IF SUBSTRING(@list_text, (@TextPos + @DelimPos - 1), @DelimLen) = @Delimiter BEGIN -- insert position INSERT INTO #list_items (item_order, item_begpos, item_endpos) VALUES (@ItemOrder, @ItemBegPos, (@TextPos + @DelimPos - 1) - 1) -- adjust positions SET @ItemOrder = @ItemOrder + 1 SET @ItemBegPos = (@TextPos + @DelimPos - 1) + @DelimLen SET @ChunkPos = @DelimPos + @DelimLen END ELSE BEGIN -- adjust positions SET @ChunkPos = @DelimPos + 1 END -- find next delimiter SET @DelimPos = CHARINDEX(@DelimChar, @Chunk, @ChunkPos) END -- adjust positions SET @TextPos = @TextPos + @ChunkLen END -- handle last item IF @ItemBegPos <= @InputLen BEGIN -- insert position INSERT INTO #list_items (item_order, item_begpos, item_endpos) VALUES (@ItemOrder, @ItemBegPos, @InputLen) END -- delete the bad items DELETE FROM #list_items WHERE item_endpos < item_begpos -- return list items SELECT SUBSTRING(@list_text, item_begpos, (item_endpos - item_begpos + 1)) AS item_text, item_order, item_begpos, item_endpos FROM #list_items ORDER BY item_order END DROP TABLE #list_items RETURN /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
-
==============================
14.그 있었다 나는 임시로 XML을 사용하여 과거에 이런 짓을했지만 동안.
그 있었다 나는 임시로 XML을 사용하여 과거에 이런 짓을했지만 동안.
나는이에 대한 모든 크레딧을받을 수 없어,하지만 난에서이 아이디어를 어디서 얻었 나는 더 이상 알고 두려워 :
-- declare the variables needed DECLARE @xml as xml,@str as varchar(100),@delimiter as varchar(10) -- The string you want to split SET @str='A,B,C,D,E,Bert,Ernie,1,2,3,4,5' -- What you want to split on. Can be a single character or a string SET @delimiter =',' -- Convert it to an XML document SET @xml = cast(('<X>'+replace(@str,@delimiter ,'</X><X>')+'</X>') as xml) -- Select back from the XML SELECT N.value('.', 'varchar(10)') as value FROM @xml.nodes('X') as T(N)
-
==============================
15.나는 사용자 KM와 같은 생각을 가지고있다. 하지만 별도의 테이블 번호가 필요하지 않습니다. 다만이 기능 만.
나는 사용자 KM와 같은 생각을 가지고있다. 하지만 별도의 테이블 번호가 필요하지 않습니다. 다만이 기능 만.
CREATE FUNCTION [dbo].[FN_ListToTable] ( @SplitOn char(1) --REQUIRED, the character to split the @List string on ,@List varchar(8000) --REQUIRED, the list to split apart ) RETURNS @ParsedList table ( ListValue varchar(500) ) AS BEGIN DECLARE @number int = 0 DECLARE @childString varchar(502) = '' DECLARE @lengthChildString int = 0 DECLARE @processString varchar(502) = @SplitOn + @List + @SplitOn WHILE @number < LEN(@processString) BEGIN SET @number = @number + 1 SET @lengthChildString = CHARINDEX(@SplitOn, @processString, @number + 1) - @number - 1 IF @lengthChildString > 0 BEGIN SET @childString = LTRIM(RTRIM(SUBSTRING(@processString, @number + 1, @lengthChildString))) IF @childString IS NOT NULL AND @childString != '' BEGIN INSERT INTO @ParsedList(ListValue) VALUES (@childString) SET @number = @number + @lengthChildString - 1 END END END RETURN END
그리고 여기 테스트입니다 :
SELECT ListValue FROM dbo.FN_ListToTable('/','a/////bb/c')
결과:
ListValue ______________________ a bb c
-
==============================
16.이 시도:
이 시도:
SELECT ProductId, Name, Tags FROM Product WHERE '1,2,3,' LIKE '%' + CAST(ProductId AS VARCHAR(20)) + ',%';
이 링크의 마지막 예에서 말했듯
-
==============================
17.
-- select * from dbo.Split_ID('77,106') ALTER FUNCTION dbo.Split_ID(@String varchar(8000)) returns @temptable TABLE (ID varchar(8000)) as begin declare @idx int declare @slice varchar(8000) declare @Delimiter char(1) set @Delimiter =',' select @idx = 1 if len(@String)<1 or @String is null return while @idx!= 0 begin set @idx = charindex(@Delimiter,@String) if @idx!=0 set @slice = left(@String,@idx - 1) else set @slice = @String if(len(@slice)>0) insert into @temptable(ID) values(@slice) set @String = right(@String,len(@String) - @idx) if len(@String) = 0 break end return end
-
==============================
18.이처럼 할 수 :
이처럼 할 수 :
create or replace PROCEDURE UDP_SETBOOKMARK ( P_USERID IN VARCHAR2 , P_BOOKMARK IN VARCHAR2 ) AS BEGIN UPDATE T_ER_Bewertung SET LESEZEICHEN = P_BOOKMARK WHERE STAMM_ID in( select regexp_substr(P_USERID,'[^,]+', 1, level) from dual connect by regexp_substr(P_USERID, '[^,]+', 1, level) is not null ) and ER_ID = (select max(ER_ID) from T_ER_Bewertung_Kopie); commit; END UDP_SETBOOKMARK;
그런 다음에 그것을 시도
Begin UDP_SETBOOKMARK ('1,2,3,4,5', 'Test'); End;
당신은 그것을 시도, 너무 다른 상황에서 REGEXP_SUBSTR으로이 IN-절을 사용할 수 있습니다.
-
==============================
19.
Error 493: The column 'i' that was returned from the nodes() method cannot be used directly. It can only be used with one of the four XML data type methods, exist(), nodes(), query(), and value(), or in IS NULL and IS NOT NULL checks.
위의 오류는 다음 코드를 사용하여 SQL 서버 2014에서 수정되었습니다
Declare @Ids varchar(50) Set @Ids = '1,2,3,5,4,6,7,98,234' DECLARE @XML XML SET @XML = CAST('<i>' + REPLACE(@Ids, ',', '</i><i>') + '</i>' AS XML) SELECT SomeTable.* FROM SomeTable cross apply @XML.nodes('i') x(i) where SomeTable .Id = x.i.value('.', 'VARCHAR(MAX)')
-
==============================
20.가장 간단한 방법.
가장 간단한 방법.
DECLARE @AccumulateKeywordCopy NVARCHAR(2000),@IDDupCopy NVARCHAR(50); SET @AccumulateKeywordCopy =''; SET @IDDupCopy =''; SET @IDDup = (SELECT CONVERT(VARCHAR(MAX), <columnName>) FROM <tableName> WHERE <clause>) SET @AccumulateKeywordCopy = ','+@AccumulateKeyword+','; SET @IDDupCopy = ','+@IDDup +','; SET @IDDupCheck = CHARINDEX(@IDDupCopy,@AccumulateKeywordCopy)
-
==============================
21.
CREATE TABLE t ( id INT, col1 VARCHAR(50) ) INSERT INTO t VALUES (1, 'param1') INSERT INTO t VALUES (2, 'param2') INSERT INTO t VALUES (3, 'param3') INSERT INTO t VALUES (4, 'param4') INSERT INTO t VALUES (5, 'param5') DECLARE @params VARCHAR(100) SET @params = ',param1,param2,param3,' SELECT * FROM t WHERE Charindex(',' + Cast(col1 AS VARCHAR(8000)) + ',', @params) > 0
바이올린 여기 바이올린 찾기 작업
-
==============================
22.내가 찾은 가장 간단한 방법은 FIND_IN_SET를 사용하는 것이 었습니다
내가 찾은 가장 간단한 방법은 FIND_IN_SET를 사용하는 것이 었습니다
FIND_IN_SET(column_name, values) values=(1,2,3) SELECT name WHERE FIND_IN_SET(id, values)
from https://stackoverflow.com/questions/878833/passing-a-varchar-full-of-comma-delimited-values-to-a-sql-server-in-function by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 왜 오라클은 NULL로 빈 문자열을 취급 9I는 무엇입니까? (0) | 2020.03.08 |
---|---|
[SQL] 어느 / 빠른 최고? SELECT * 또는 SELECT 컬럼 1, colum2, 3 열, 등 (0) | 2020.03.08 |
[SQL] 다양한 SELECT 쿼리의 결과를 반환하는 PL / pgSQL의 함수 리팩토링 (0) | 2020.03.08 |
[SQL] SQLite는 - UPSERT *하지 * INSERT 또는 REPLACE (0) | 2020.03.08 |
[SQL] 외래 키 제약은 사이클 또는 여러 개의 캐스케이드 경로의 원인? (0) | 2020.03.08 |