просто хотел поделиться, как мы реализовали ручной способ
int maxSizeForAllFiles = 70000; // Read from property
int sizePerFile = 22000; // Red from property
/**
* Iterate all attachment list to verify if ZIP is required
*/
for (String attachFile : inputAttachmentList) {
File file = new File(attachFile);
totalFileSize += file.length();
/**
* if ZIP required ??? based on the size
*/
if (file.length() >= sizePerFile) {
toBeZipped = true;
logger.info("File: "
+ attachFile
+ " Size: "
+ file.length()
+ " File required to be zipped, MAX allowed per file: "
+ sizePerFile);
break;
}
}
/**
* Check if all attachments put together cross MAX_SIZE_FOR_ALL_FILES
*/
if (totalFileSize >= maxSizeForAllFiles) {
toBeZipped = true;
}
if (toBeZipped) {
// Zip Here iterating all attachments
}
Erland Sommarskog поддерживал авторитетный ответ на этот вопрос в течение прошлых 16 лет: Массивы и Списки в SQL Server.
существует по крайней мере дюжина способов передать массив или список к запросу; у каждого есть их собственные уникальные за и против.
я действительно не могу рекомендовать достаточно [1 112], читает статью для приобретения знаний о компромиссах среди всех этих опций.
Вы могли использовать XML.
, Например,
declare @xmlstring as varchar(100)
set @xmlstring = '<args><arg value="42" /><arg2>-1</arg2></args>'
declare @docid int
exec sp_xml_preparedocument @docid output, @xmlstring
select [id],parentid,nodetype,localname,[text]
from openxml(@docid, '/args', 1)
команда sp_xml_preparedocument встроена.
Это произвело бы вывод:
id parentid nodetype localname text
0 NULL 1 args NULL
2 0 1 arg NULL
3 2 2 value NULL
5 3 3 #text 42
4 0 1 arg2 NULL
6 4 3 #text -1
, который имеет все (больше?) того, в чем Вы Вы нуждаетесь.
Да, Ваше текущее решение подвержено атакам с использованием кода на SQL.
лучшее решение, которое я нашел, состоит в том, чтобы использовать функцию, которая разделяет текст на слова (существуют некоторые отправленные здесь, или можно использовать этот из моего блога ), и затем соедините это с таблицей. Что-то как:
SELECT d.[Name]
FROM Department d
JOIN dbo.SplitWords(@DepartmentIds) w ON w.Value = d.DepartmentId
Один метод, который Вы могли бы хотеть рассмотреть, собираетесь ли Вы быть работой со значениями много, должен записать им во временную таблицу сначала. Тогда Вы просто присоединяетесь на нем как нормальный.
Таким образом, Вы только анализируете однажды.
является самым легким использовать одно из 'Разделения' UDFs, но столько людей отправило примеры тех, я полагал, что пойду различным путем;)
Этот пример составит временную таблицу для Вас, чтобы присоединиться на (#tmpDept) и заполнить его идентификатором отдела, в котором Вы передали. Я предполагаю, что Вы разделяете их с запятыми, но Вы можете - конечно - изменяют его на то, что Вы хотите.
IF OBJECT_ID('tempdb..#tmpDept', 'U') IS NOT NULL
BEGIN
DROP TABLE #tmpDept
END
SET @DepartmentIDs=REPLACE(@DepartmentIDs,' ','')
CREATE TABLE #tmpDept (DeptID INT)
DECLARE @DeptID INT
IF IsNumeric(@DepartmentIDs)=1
BEGIN
SET @DeptID=@DepartmentIDs
INSERT INTO #tmpDept (DeptID) SELECT @DeptID
END
ELSE
BEGIN
WHILE CHARINDEX(',',@DepartmentIDs)>0
BEGIN
SET @DeptID=LEFT(@DepartmentIDs,CHARINDEX(',',@DepartmentIDs)-1)
SET @DepartmentIDs=RIGHT(@DepartmentIDs,LEN(@DepartmentIDs)-CHARINDEX(',',@DepartmentIDs))
INSERT INTO #tmpDept (DeptID) SELECT @DeptID
END
END
Это позволит Вам передавать в одном идентификаторе отдела, несколько идентификатор с запятыми, промежуточными их, или даже несколько идентификатор с запятыми и пробелами между ними.
Поэтому, если Вы сделали что-то как:
SELECT Dept.Name
FROM Departments
JOIN #tmpDept ON Departments.DepartmentID=#tmpDept.DeptID
ORDER BY Dept.Name
Вы видели бы названия всех идентификаторов отдела, в которых Вы передали...
Снова, это может быть упрощено при помощи функции для заполнения временной таблицы... Я главным образом сделал это без одного только для уничтожения некоторой скуки:-p
- Kevin Fairchild