Конкатенация SQL Server JSON для динамических запросов

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

0
задан Larnu 15 January 2019 в 10:54
поделиться

1 ответ

Последний опубликованный вами запрос также не является динамическим, поэтому я не уверен, почему вы используете EXEC. Как я уже упоминал в комментариях, поэтому это так же просто, как использовать SET:

DECLARE @PropertyPK uniqueidentifier; --SP parameter

DECLARE @JSON nvarchar(MAX);

SET @JSON = (SELECT *
             FROM Contacts
             WHERE PropertyPK = @PropertyPK
             FOR JSON PATH, INCLUDE_NULL_VALUES);

Нет необходимости приводить @PropertyPK как varchar к динамическому оператору SQL; просто используйте правильный параметризованный SQL.

Это основано на догадках и последнем (но явно неполном) вопросе ОП. Если это не правильно, это должно привести вас к правильному пути, однако, из-за того, что информация потечет, затруднительно ответить на вопрос.

DECLARE @PropertyPK uniqueidentifier,
        @SearchTerm varchar(50),
        @Limit int,
        @Offset int,
        @SortBy sysname,  --objects have the data type sysname, aka nvarchar(128)
        @SortOrder nvarchar(4); --Guess datatype as it was missing in your sample

DECLARE @JSON nvarchar(MAX);

DECLARE @SQL nvarchar(MAX);


SET @SQL = N'SET @JSON = (SELECT {Columns}' + NCHAR(10) + --Replace {Columns} with an actual list of the required columns (NOT *)
           N'             FROM dbo.Contacts' + NCHAR(10) +
           N'             WHERE Address LIKE @Search' + NCHAR(10) +
           N'               AND PropertyPK = @PropertyPK' + NCHAR(10) + --I ASSUME that WHERE is still needed
           N'             ORDER BY ' + QUOTENAME(@SortBy) + N' ' + CASE @SortOrder WHEN N'ASC' THEN N'ASC' WHEN N'DESC' THEN 'DESC' END + NCHAR(10) + --The CASE stops invalid sort orders
           N'             OFFSET @Offset FEETCH NEXT @Limit ROWS ONLY' + NCHAR(10) +
           N'             FOR JSON PATH, INCLUDE_NULL_VALUES);';

PRINT @SQL; --Your best friend
EXEC sp_executesql @SQL,
                   N'@JSON nvarchar(MAX) OUTPUT, @Search varchar(50), @PropertyPK uniqueidentifier, @Offset int, @Limit int',
                   @JSON = @JSON OUTPUT, 
                   @Search = @SearchTerm,
                   @PropertyPK = @PropertyPK,
                   @Offset = @Offset,
                   @Limit = @Limit;

Одна из самых важных вещей, которую вы должны здесь отметить, это то, что я сделал SQL БЕЗОПАСНЫМ . Ваш SQL был широко открыт для внедрения SQL, что является огромным недостатком безопасности. Если вы не знаете / не понимаете SQL-инъекцию, я предлагаю прочитать об этом сейчас. SQL, как у вас выше, - это огромная проблема, а конкатенация необработанных строк - ужасная идея, ожидающая своего использования.

0
ответ дан Larnu 15 January 2019 в 10:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: