Strange String.Format () — входная строка имела неправильный формат

Кажется, я не могу понять, почему у меня возникают проблемы, поскольку я делал это несколько раз, но с этой строкой, которую нужно отформатировать string fsql = string.Format(sql, fa);, я получаю сообщение об ошибке: Input string was not in a correct format case.

sql:

"DECLARE @BENTEST varchar(100)\r\nSET @BENTEST = '{1}'\r\n\r\nSELECT a.Period, a.NCR, a.Date_Created, a.Date_Done, a.Item, a.Qty, tc.TargetCost*a.Qty Cost, a.Aging FROM\r\n\t(SELECT \r\n\tnt.NCR, \r\n\tDATENAME(yy, nt.Date_Done) + '-' + RIGHT('0' + DATENAME(ISOWK, nt.Date_Done), 2) Period,\r\n\tnt1.Date_Created,\r\n\tnt.Date_Done,\r\n\t(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%\"%', a.FirstParseStep)) ParsedItem FROM\r\n\t\t(SELECT SUBSTRING(nt.ItemData, PATINDEX('%\"Item%', nt.ItemData) + LEN('\"Item\":\"'), 60) FirstParseStep) a) Item,\r\n\t(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}%', a.FirstParseStep)) ParsedQuantity FROM\r\n\t\t(SELECT SUBSTRING(nt.ItemData, PATINDEX('%\"ItemQty%', nt.ItemData) + LEN('\"ItemQty\":'), 60) FirstParseStep) a ) Qty,\r\n\tPCF.dbo.GetRealWorkDays(nt1.Date_Created, nt.Date_Done) Aging\r\n\tFROM PCF.dbo.NCRTask nt, PCF.dbo.NCRTask nt1\r\n\tWHERE nt1.NCR = nt.NCR\r\n\tAND (nt.TaskType = 5 OR nt.TaskType = 16)\r\n\tAND nt1.TaskType = 25\r\n\tUNION\r\n\tSELECT \r\n\tnt.NCR, \r\n\tDATENAME(yy, @BENTEST) + '-' + RIGHT('0' + DATENAME(ISOWK, @BENTEST), 2) Period,\r\n\tnt.Date_Created,\r\n\tnull Date_Done,\r\n\t(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%\"%', a.FirstParseStep)) ParsedItem FROM\r\n\t\t(SELECT SUBSTRING(nt.ItemData, PATINDEX('%\"Item%', nt.ItemData) + LEN('\"Item\":\"'), 60) FirstParseStep) a) Item,\r\n\t(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}%', a.FirstParseStep)) ParsedQuantity FROM\r\n\t\t(SELECT SUBSTRING(nt.ItemData, PATINDEX('%\"ItemQty%', nt.ItemData) + LEN('\"ItemQty\":'), 60) FirstParseStep) a ) Qty,\r\n\tPCF.dbo.GetRealWorkDays(nt.Date_Created, GETDATE()) Aging\r\n\tFROM PCF.dbo.NCRTask nt\r\n\tWHERE nt.TaskType = 25\r\n\tAND nt.Date_Created < @BENTEST\r\n\tAND NOT EXISTS (SELECT 1 FROM PCF.dbo.NCRTask WHERE nt.NCR = NCR AND (TaskType = 5 OR TaskType = 16) AND Date_Done < @BENTEST)) a,\r\n\tavvik1.dbo.TargetCost tc\r\nWHERE a.Period = DATENAME(yy, @BENTEST) + '-' + RIGHT('0' + DATENAME(ISOWK, @BENTEST), 2)\r\nAND tc.ItemNo = a.Item"

sql, но отформатирован так, чтобы его было легко прочитать:

DECLARE @BENTEST varchar(100)
SET @BENTEST = '{1}'

SELECT a.Period, a.NCR, a.Date_Created, a.Date_Done, a.Item, a.Qty, tc.TargetCost*a.Qty Cost, a.Aging FROM
    (SELECT 
    nt.NCR, 
    DATENAME(yy, nt.Date_Done) + '-' + RIGHT('0' + DATENAME(ISOWK, nt.Date_Done), 2) Period,
    nt1.Date_Created,
    nt.Date_Done,
    (SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%"%', a.FirstParseStep)) ParsedItem FROM
        (SELECT SUBSTRING(nt.ItemData, PATINDEX('%"Item%', nt.ItemData) + LEN('"Item":"'), 60) FirstParseStep) a) Item,
    (SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}%', a.FirstParseStep)) ParsedQuantity FROM
        (SELECT SUBSTRING(nt.ItemData, PATINDEX('%"ItemQty%', nt.ItemData) + LEN('"ItemQty":'), 60) FirstParseStep) a ) Qty,
    PCF.dbo.GetRealWorkDays(nt1.Date_Created, nt.Date_Done) Aging
    FROM PCF.dbo.NCRTask nt, PCF.dbo.NCRTask nt1
    WHERE nt1.NCR = nt.NCR
    AND (nt.TaskType = 5 OR nt.TaskType = 16)
    AND nt1.TaskType = 25
    UNION
    SELECT 
    nt.NCR, 
    DATENAME(yy, @BENTEST) + '-' + RIGHT('0' + DATENAME(ISOWK, @BENTEST), 2) Period,
    nt.Date_Created,
    null Date_Done,
    (SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%"%', a.FirstParseStep)) ParsedItem FROM
        (SELECT SUBSTRING(nt.ItemData, PATINDEX('%"Item%', nt.ItemData) + LEN('"Item":"'), 60) FirstParseStep) a) Item,
    (SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}%', a.FirstParseStep)) ParsedQuantity FROM
        (SELECT SUBSTRING(nt.ItemData, PATINDEX('%"ItemQty%', nt.ItemData) + LEN('"ItemQty":'), 60) FirstParseStep) a ) Qty,
    PCF.dbo.GetRealWorkDays(nt.Date_Created, GETDATE()) Aging
    FROM PCF.dbo.NCRTask nt
    WHERE nt.TaskType = 25
    AND nt.Date_Created < @BENTEST
    AND NOT EXISTS (SELECT 1 FROM PCF.dbo.NCRTask WHERE nt.NCR = NCR AND (TaskType = 5 OR TaskType = 16) AND Date_Done < @BENTEST)) a,
    avvik1.dbo.TargetCost tc
WHERE a.Period = DATENAME(yy, @BENTEST) + '-' + RIGHT('0' + DATENAME(ISOWK, @BENTEST), 2)
AND tc.ItemNo = a.Item

fa — это строка[], состоящая из:

[0] = ""
[1] = date with format "YYYY-MM-DD"

Я не могу понять, почему я получаю ошибку. Я сделал это для некоторых других sql: s, и у меня нет этой проблемы. Кто-нибудь знает, что случилось?


person President Camacho    schedule 19.03.2015    source источник
comment
Можем ли мы также увидеть ваш код C#?   -  person Soner Gönül    schedule 19.03.2015
comment
Зачем ты это делаешь? Не используйте string.Format() для помещения значений параметров в ваш SQL.   -  person JLRishe    schedule 19.03.2015
comment
@JLRishe, почему бы и нет? Sql отличается каждый раз, когда я не могу объединить строку, когда sql устанавливается динамически.   -  person President Camacho    schedule 19.03.2015
comment
Вместо этого DECLARE @BENTEST varchar(100)\r\nSET @BENTEST = '{1} ... начинается с {0}, как в `DECLARE @BENTEST varchar(100)\r\nSET @BENTEST = '{0} .... Тем не менее, вам также нужно исправить этот одинокий } в середине строки sql-. Вместо этого я бы использовал хранимую процедуру. Затем вы можете передавать аргументы через sql-параметр.   -  person Tim Schmelter    schedule 19.03.2015
comment
@Tim Schmelter не следует игнорировать [0] в fa, потому что в строке sql нет {0}?   -  person President Camacho    schedule 19.03.2015
comment
@PresidentCamacho Нет, насколько я вижу, SQL каждый раз один и тот же. Это просто одно значение, которое отличается. Поэтому используйте параметризованный SQL ради всего святого.   -  person JLRishe    schedule 19.03.2015
comment
Или ради Bobby Tables.   -  person Jon Skeet    schedule 19.03.2015
comment
@PresidentCamacho: это не [0], а {1}, и это не игнорируется. Сообщение Индекс (с нуля) должен быть больше или равен нулю и меньше размера списка аргументов.   -  person Tim Schmelter    schedule 19.03.2015
comment
@TimSchmelter Нет проблем с передачей двух значений параметров и использованием только {1}. Как говорит OP, элемент 0th будет просто проигнорирован.   -  person JLRishe    schedule 19.03.2015
comment
@TimSchmelter, string.Format будет опускать каждый аргумент в списке параметров, если в строке формата нет подходящего заполнителя.   -  person Hamlet Hakobyan    schedule 19.03.2015
comment
@JLRishe да, использование String.Format глупо, учитывая, что вы можете вводить sql, но почему текущий код генерирует ошибку? Я пытался объявить BENTEST как datetime и varchar, но оба дают одну и ту же ошибку.   -  person President Camacho    schedule 19.03.2015
comment
@PresidentCamacho Я не знаю. Это гигантская строка, и предположительно string.Format что-то в ней не нравится. Он не предназначен для таких вводов. Редактировать: у PetSerAl есть ответ.   -  person JLRishe    schedule 19.03.2015
comment
@HamletHakobyan: конечно? string.Format("{1}", "test"); стрела   -  person Tim Schmelter    schedule 19.03.2015
comment
@TimSchmelter Нет, это не аналог. То, что делает OP, эквивалентно string.Format("{1}", "test", "test2");.   -  person JLRishe    schedule 19.03.2015
comment
@JLRishe: я почти уверен, что массив OP содержит одну строку.   -  person Tim Schmelter    schedule 19.03.2015
comment
@TimSchmelter Цитирую: fa - это string[], и он состоит из: [0] = "" [1] = date with format "YYYY-MM-DD". И проблема, которую вы описываете, не приведет к ошибке, которую получает OP.   -  person JLRishe    schedule 19.03.2015
comment
@JLRishe: спасибо, я пропустил эту часть.   -  person Tim Schmelter    schedule 19.03.2015


Ответы (2)


В вашей строке есть неэкранированный }:

(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}%', a.FirstParseStep)) ParsedQuantity FROM
                                                  ^

Вы должны избежать этого:

(SELECT SUBSTRING(a.FirstParseStep, 0, PATINDEX('%}}%', a.FirstParseStep)) ParsedQuantity FROM
person user4003407    schedule 19.03.2015

Из того, что я вижу, вы просто поместили 2 переменные в string.Format, однако вы никогда не устанавливали строку и не говорили ей использовать переменные. возможно, вы хотели сделать что-то вроде этого? :

string fsql = string.Format("{0} {1}":sql, fa);

так как вам нужно отказаться от строки, и вы можете использовать {} с индексом переменной, указанной за строкой, вместо того, чтобы просто объявлять строки. для получения дополнительной информации о String.Format см. MSDN

person maam27    schedule 19.03.2015
comment
Я не могу это использовать. Форматируемая строка может быть бесконечным числом переменных, подлежащих замене. Тогда fa также должно быть бесконечно длинным. - person President Camacho; 19.03.2015