Скалярная функция SQL - PullRequest
       28

Скалярная функция SQL

2 голосов
/ 14 марта 2019

Я ищу, чтобы получить значение прибыли (FilmBoxOfficeDollar - FilmBudgetDollars) на основе Studio, заданной в качестве параметра функции.

USE Movies;

GO

CREATE FUNCTION fnmovieProfits(@StudioName nvarchar(255))
  RETURNS int
AS
BEGIN
  RETURN (SELECT SUM(FilmBoxOfficeDollars - FilmBudgetDollars)
      FROM Film JOIN Studio
      ON Film.FilmStudioID = Studio.StudioID
      WHERE StudioName = @StudioName);  
END;

GO
SELECT [dbo].[fnmovieProfits]('Dreamworks');

Всякий раз, когда я запускаю это для извлечения фрагмента данныхЯ получаю следующую ошибку:

Msg 8115, Level 16, State 2, Line 13
Arithmetic overflow error converting expression to data type int.

Любая помощь будет высоко ценится!

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Проблема, с которой вы сталкиваетесь, заключается в том, что вы переполняете допустимое значение 32-разрядного числа (INT); если вы приведете / преобразуете в 64-битное число (BIGINT) и вернете этот тип данных, проблема будет исправлена. Подтверждение концепции, показывающее проблему:

DECLARE @BigNumber INT=2000000000
select CONVERT(BIGINT,@BigNumber) + CONVERT(BIGINT,@BigNumber) --returns 4,000,000,000
select (@BigNumber + @BigNumber) --errors with "Arithmetic overflow error converting expression to data type int."

НО , сделайте себе одолжение и используйте вместо этого вид. Такие скаляры ужасны для производительности в отчетах. Скалярные функции никогда не должны использоваться, если они просто не выполняют вычисления, основанные на входных значениях (то есть не затрагивая базовые, постоянные данные).

CREATE VIEW dbo.v_StudioProfits
AS
   SELECT
      StudioName,
      SUM(CONVERT(BIGINT,FilmBoxOfficeDollars) - CONVERT(BIGINT,FilmBudgetDollars)) AS [Profit]
   FROM Film
   INNER JOIN Studio ON Film.FilmStudioID = Studio.StudioID
   GROUP BY StudioName
GO

SELECT * FROM dbo.v_StudioProfits WHERE StudioName='Dreamworks'

Релевантно чтение для типов данных SQL Server. В частности, целочисленные типы данных .

0 голосов
/ 14 марта 2019

Ваша сумма превышает int диапазон.Вы должны определить тип возврата как bigint:

CREATE FUNCTION fnmovieProfits(@StudioName nvarchar(255))
  RETURNS bigint
AS.......

Максимальное значение, которое вы можете вернуть с помощью int, в качестве типа возврата - 2147483647.Ваш sum, вероятно, больше этого значения.

Один пример функции, которая превышает тип возвращаемого значения:

CREATE FUNCTION testFunction()
  RETURNS int
AS
BEGIN
  RETURN (SELECT 2147483647 + 1);  
END;

GO
SELECT [dbo].[testFunction]();

Если вы выполните его, вы получите следующую ошибку:

Msg 8115, Level 16, State 2, Line 8
Arithmetic overflow error converting expression to data type int.

Таким образом, решение состоит в том, чтобы просто увеличить диапазон возвращаемых типов, заменив int на bigint.

...