Nano Hash - криптовалюты, майнинг, программирование

Многозначный параметр даты в хранимой процедуре?

Я пытаюсь заставить работать хранимую процедуру, которая принимает многозначный параметр для дат. Этого нет в SSRS, но я пытаюсь использовать тот же подход, что и с ним:

ALTER PROCEDURE spSelectPlacementData
(
    @ClientID           SMALLINT,
    @SourceFileDates    VARCHAR(MAX)
)
AS
BEGIN
    SELECT (snip)
    FROM [APS].[dbo].[Account] A
    WHERE ClientID = @ClientID
    AND A.[SourceFileDate] IN (SELECT * FROM dbo.Split(@SourceFileDates))
END

Я использую этот подход с полями INT и VARCHAR в многозначных параметрах отчета SSRS.

Вот код, который я использую для объединения SourceFileDates:

    string sourceFileDates = "";

    foreach (DateTime file in job.sourceFiles)
    {
        if (file == job.sourceFiles.Last())
        {
            sourceFileDates += "'" + file.ToString("d") + "'";
        }
        else
        {
            sourceFileDates += "'" + file.ToString("d") + "', ";
        }
    }

    selectRunCommand = new SqlCommand("spSelectPlacementData", sqlConnection);
    selectRunCommand.CommandType = CommandType.StoredProcedure;
    selectRunCommand.Parameters.Add("@ClientID", SqlDbType.SmallInt);
    selectRunCommand.Parameters["@ClientID"].Value = job.clientID;
    selectRunCommand.Parameters.Add("@SourceFileDates", SqlDbType.VarChar);
    selectRunCommand.Parameters["@SourceFileDates"].Value = sourceFileDates;

Используя эту функцию dbo.Split, которую я схватил онлайн:

/****** Object:  UserDefinedFunction [dbo].[Split]    Script Date: 09/20/2011 11:16:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Split]
/* This function is used to split up multi-value parameters */
(
@ItemList VARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @IDTable TABLE (Item VARCHAR(MAX) collate database_default )
AS
BEGIN
DECLARE @tempItemList VARCHAR(MAX)
SET @tempItemList = @ItemList

DECLARE @i INT
DECLARE @Item VARCHAR(MAX)

SET @tempItemList = REPLACE (@tempItemList, @delimiter + ' ', @delimiter)
SET @i = CHARINDEX(@delimiter, @tempItemList)

WHILE (LEN(@tempItemList) > 0)
BEGIN
IF @i = 0
SET @Item = @tempItemList
ELSE
SET @Item = LEFT(@tempItemList, @i - 1)

INSERT INTO @IDTable(Item) VALUES(@Item)

IF @i = 0
SET @tempItemList = ''
ELSE
SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i)

SET @i = CHARINDEX(@delimiter, @tempItemList)
END
RETURN
END

Я думаю, я не совсем понимаю, в чем разница между тем, как я форматирую параметр, как SSRS делает это для аналогичных параметров (это единственное, что я пытался сделать из кода), и как тип данных Date влияет на требуемый форматирование. Я получаю сообщение «Ошибка преобразования при преобразовании даты и/или времени из символьной строки». ошибка при выборе более одного значения.

Изменить: по запросу пример вывода цикла foreach:

'9/9/2011', '8/19/2011', '8/12/2011'


  • Показать значение sourceFileDates после цикла foreach 20.09.2011

Ответы:


1

Почему бы не использовать параметр с табличным значением?

Создайте определяемый пользователем тип таблицы DateTimes на SQL

create type DateTimes as table
(
    [Value] datetime
)

Затем измените хранимую процедуру:

ALTER PROCEDURE spSelectPlacementData
(
    @ClientID           SMALLINT,
    @SourceFileDates    DateTimes readonly -- must be readonly
)

Теперь вы можете рассматривать @SourceFileDates как табличную переменную только для чтения.

При указании параметров SqlCommand параметр с табличным значением указывается как SqlDbType.Structured и передается как DataTable или < a href="http://msdn.microsoft.com/en-us/library/system.data.datarowcollection.aspx" rel="nofollow">DataRowcollection. Итак, вы можете заполнить его так:

var sourceFileDates = new DataTable();
sourceFileDates.Columns.Add("Value", typeof(DateTime));
foreach (DateTime file in job.sourceFiles)
{
    sourceFileDates.Rows.Add(file);
}
selectRunCommand.Parameters.Add(new SqlParameter {
    ParameterName = "@SourceFileDates", 
    Value = sourceFileDates,
    SqlDbType = SqlDbType.Structured // make sure you specify structured
});

Теперь все красиво и правильно набрано... и вам не нужно выполнять синтаксический анализ или преобразование строк.

В качестве примечания вы могли бы также создать типы Strings и Integers; Вы подсядете на TVP и будете использовать их повсюду.

20.09.2011
  • Это похоже на то, что я ищу, я понятия не имел, что они существуют. Я попробую, спасибо! 20.09.2011
  • Очень хорошая реализация и объяснение. Поставлю +1, как только смогу (на сегодня нет голосов). 20.09.2011
  • Я не возражал, я делал заметку ... для ОП ваш ответ - совершенно законное и элегантное решение. Однако кто-то, кто ищет что-то подобное в Google, может быть разочарован тем, что это не работает в их системе 2005 года. 20.09.2011

  • 2

    SSRS немного обманывает, потому что контролирует входные данные... он не так обеспокоен атаками SQL Injection. С помощью хранимой процедуры это будет сделать немного сложнее.

    Что хорошо сработало для меня, когда мне нужно было отправить несколько значений в одном аргументе в 2005 году, я бы отправил их в виде строки XML, например:

    <dates>
        <date>2011-01-23</date>
        <date>2011-02-24</date>
    </dates>
    

    а затем обработайте это как таблицу в функции:

    select 
        x.a.value('.', 'datetime') as myDate
    from
        @XMLArg.nodes('/dates/date') x(a);
    

    теперь вы должны иметь свои данные как табличные. (синтаксис может быть немного неправильным, это не в моей голове)

    20.09.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..