Как установить строку по умолчанию для запроса, который не возвращает строк?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

29
задан Taryn 16 July 2013 в 19:47
поделиться

8 ответов

Один подход для Oracle:

SELECT val
FROM myTable
UNION ALL
SELECT 'DEFAULT'
FROM dual
WHERE NOT EXISTS (SELECT * FROM myTable)

Или альтернативно в Oracle:

SELECT NVL(MIN(val), 'DEFAULT')
FROM myTable

Или альтернативно в SqlServer:

SELECT ISNULL(MIN(val), 'DEFAULT')
FROM myTable

Они используют то, что MIN() возвраты NULL, когда нет никаких строк.

38
ответ дан WW. 28 November 2019 в 01:06
поделиться

Если Ваш основной запрос, как ожидают, возвратит только одну строку, то Вы могли использовать этот прием:

select NVL( MIN(rate), 0 ) AS rate 
from d_payment_index
where fy = 2007
  and payment_year = 2008
  and program_id = 18

(код Oracle, не уверенный, если NVL является правильной функцией для SQL Server.)

13
ответ дан Dave Costa 28 November 2019 в 01:06
поделиться

Это было бы, устраняют запрос Select из выполнения дважды и быть лучше для производительности:

Declare @rate int

select 
    @rate = rate 
from 
    d_payment_index
where 
    fy = 2007
    and payment_year = 2008
    and program_id = 18

IF @@rowcount = 0
    Set @rate = 0

Select @rate 'rate'
10
ответ дан duckworth 28 November 2019 в 01:06
поделиться

Как насчет этого:

SELECT DEF.Rate, ACTUAL.Rate, COALESCE(ACTUAL.Rate, DEF.Rate) AS UseThisRate
FROM 
  (SELECT 0) DEF (Rate) -- This is your default rate
LEFT JOIN (
  select rate 
  from d_payment_index
  --WHERE 1=2   -- Uncomment this line to simulate a missing value

  --...HERE IF YOUR ACTUAL WHERE CLAUSE. Removed for testing purposes...
  --where fy = 2007
  -- and payment_year = 2008
  --  and program_id = 18
) ACTUAL (Rate) ON 1=1

Результаты

Допустимый Уровень Существует

Rate        Rate        UseThisRate
----------- ----------- -----------
0           1           1

Уровень По умолчанию, Используемый

Rate        Rate        UseThisRate
----------- ----------- -----------
0           NULL        0

Тестовый DDL

CREATE TABLE d_payment_index (rate int NOT NULL)
INSERT INTO d_payment_index VALUES (1)
6
ответ дан beach 28 November 2019 в 01:06
поделиться

Я понял это, и это должно также работать на другие системы также. Это - изменение ответа WW.

select rate 
from d_payment_index
where fy = 2007
  and payment_year = 2008
  and program_id = 18
union
select 0 as rate 
from d_payment_index 
where not exists( select rate 
                  from d_payment_index
                  where fy = 2007
                    and payment_year = 2008
                    and program_id = 18 )
2
ответ дан John Baughman 28 November 2019 в 01:06
поделиться

Один метод сканирования таблицы с помощью левого соединения от значений по умолчанию до фактических данных:

CREATE TABLE [stackoverflow-285666] (k int, val varchar(255))

INSERT  INTO [stackoverflow-285666]
VALUES  (1, '1-1')
INSERT  INTO [stackoverflow-285666]
VALUES  (1, '1-2')
INSERT  INTO [stackoverflow-285666]
VALUES  (1, '1-3')
INSERT  INTO [stackoverflow-285666]
VALUES  (2, '2-1')
INSERT  INTO [stackoverflow-285666]
VALUES  (2, '2-2')

DECLARE @k AS int
SET @k = 0

WHILE @k < 3
    BEGIN
        SELECT  @k AS k
               ,COALESCE(ActualValue, DefaultValue) AS [Value]
        FROM    (
                 SELECT 'DefaultValue' AS DefaultValue
                ) AS Defaults
        LEFT JOIN (
                   SELECT   val AS ActualValue
                   FROM     [stackoverflow-285666]
                   WHERE    k = @k
                  ) AS [Values]
                ON 1 = 1

        SET @k = @k + 1
    END

DROP TABLE [stackoverflow-285666]

Дает вывод:

k           Value
----------- ------------
0           DefaultValue

k           Value
----------- ------------
1           1-1
1           1-2
1           1-3

k           Value
----------- ------------
2           2-1
2           2-2
2
ответ дан Cade Roux 28 November 2019 в 01:06
поделиться

Вы хотите возвратить всю строку? Строка по умолчанию должна иметь значения по умолчанию, или это может быть пустая строка? Вы хотите, чтобы строка по умолчанию имела ту же структуру столбца как рассматриваемая таблица?

В зависимости от Ваших требований, Вы могли бы сделать что-то вроде этого:

1) выполняет запрос и помещенные результаты во временной таблице (или табличная переменная) 2) проверка, чтобы видеть, имеет ли временная таблица результаты, 3) в противном случае возвращают пустую строку путем выполнения избранного оператора, подобного этому (в SQL Server):

select '' as columnA, '' as columnB, '' as columnC from #tempTable

, Где columnA, columnB и columnC являются Вашими фактическими именами столбцов.

1
ответ дан Jason Anderson 28 November 2019 в 01:06
поделиться

Вставьте значения по умолчанию в переменную таблицы, а затем обновите единственную строку этого tableVar в соответствии с фактической таблицей. Если строка найдена, tableVar будет обновлен; если нет, значение по умолчанию остается. Вернуть табличную переменную.

    ---=== The table & its data
    CREATE TABLE dbo.Rates (
        PkId int,
        name varchar(10),
        rate decimal(10,2)
    )
    INSERT INTO dbo.Rates(PkId, name, rate) VALUES (1, 'Schedule 1', 0.1)
    INSERT INTO dbo.Rates(PkId, name, rate) VALUES (2, 'Schedule 2', 0.2)

Вот решение:

---=== The solution 
CREATE PROCEDURE dbo.GetRate 
  @PkId int
AS
BEGIN
  DECLARE @tempTable TABLE (
    PkId int, 
    name varchar(10), 
    rate decimal(10,2)
 )

 --- [1] Insert default values into @tempTable. PkId=0 is dummy value  
 INSERT INTO @tempTable(PkId, name, rate) VALUES (0, 'DEFAULT', 0.00)

 --- [2] Update the single row in @tempTable with the actual value.
 ---     This only happens if a match is found
 UPDATE @tempTable
    SET t.PkId=x.PkId, t.name=x.name, t.rate = x.rate
    FROM @tempTable t INNER JOIN dbo.Rates x
    ON t.PkId = 0
    WHERE x.PkId = @PkId

 SELECT * FROM @tempTable
END

Проверьте код:

EXEC dbo.GetRate @PkId=1     --- returns values for PkId=1
EXEC dbo.GetRate @PkId=12314 --- returns default values
0
ответ дан Y-Mi Wong 28 November 2019 в 01:06
поделиться
Другие вопросы по тегам:

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