C # и SQL Server: получить результат из хранимой процедуры - PullRequest
1 голос
/ 20 мая 2011

У меня есть следующая хранимая процедура, которая вычисляет максимальные значения для нескольких столбцов.Я достиг того же результата, используя длительный выбор объединения, однако меня просто интересует разница в производительности.Используя параметр SQL направления C # либо выходного, либо возвращаемого значения, я хотел бы вернуть только значение оператора select, помеченного как "- НЕОБХОДИМО ПОЛУЧИТЬ ЭТО ЗНАЧЕНИЕ ВЕРНУТО".

Я попытался создать переменную OUTPUTзатем используйте синтаксис SET для сохранения значения, затем синтаксис RETURN.Но безрезультатно.Получил ошибки, которые мне нужны для создания переменных, которые уже есть.Я не понимаю объем переменных, кажется.(Тем временем я удалил это из кода)

Вот мой SP:

CREATE PROCEDURE sp_GetMaximumMax
  @FromDate DateTime,
  @ToDate DateTime,
  @TableName VarChar(150)
AS

DECLARE @SQL NVARCHAR(512), @ColumnName VARCHAR(150)
DECLARE @Result TABLE (Result int)

DECLARE read_cursor CURSOR FOR
   SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS  
   WHERE TABLE_NAME = @TableName 
     AND (column_name != 'id' AND column_name !='time' AND column_name !='no')

OPEN read_cursor;

FETCH NEXT FROM read_cursor INTO @ColumnName;

SET @SQL = 'SELECT MAX(['+@ColumnName+']) FROM '+@TableName+' WHERE [time] BETWEEN '''+CONVERT(VARCHAR, @FromDate, 120)+''' AND '''+CONVERT(VARCHAR, @ToDate, 120)+'''';

WHILE @@FETCH_STATUS = 0
BEGIN
Print @SQL
INSERT  @Result 
EXEC(@SQL);
FETCH NEXT FROM read_cursor
END

-- NEED TO GET THIS VALUE RETURNED
SELECT MAX(Result) AS MaxVar from @Result

CLOSE read_cursor;
DEALLOCATE read_cursor;

При этом мой исправленный код:

CREATE PROCEDURE sp_GetMaximumAvg

@FromDate DateTime,
@ToDate DateTime,
@TableName VarChar(150)

AS
CREATE TABLE #Fields(FieldName VARCHAR(150)) -- store column names
CREATE TABLE #Data(FieldName DECIMAL) -- store max values
DECLARE @ColumnName VARCHAR(150)
DECLARE @SQL VARCHAR(512)

-- add fields into field table
INSERT INTO #Fields (FieldName) SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS      WHERE TABLE_NAME = @TableName AND (column_name != 'id' AND column_name !='time' AND column_name !='no')

DECLARE @Field VARCHAR(150)
DECLARE @MyOutput INT
DECLARE ReadDaRow CURSOR

FOR SELECT * FROM #Fields

OPEN ReadDaRow
FETCH ReadDaRow INTO @Field
WHILE(@@FETCH_STATUS=0) BEGIN
SET @SQL = 'SELECT AVG(['+@Field+']) FROM '+@TableName+' WHERE [time] BETWEEN '''+CONVERT(VARCHAR, @FromDate, 120)+''' AND '''+CONVERT(VARCHAR, @ToDate, 120)+'''';
PRINT @SQL
INSERT INTO #Data EXEC(@SQL)
FETCH ReadDaRow INTO @Field
END

SELECT @MyOutput = MAX(FieldName) FROM #Data

RETURN @MyOutput

CLOSE ReadDaRow
DEALLOCATE ReadDaRow

DROP TABLE #Fields
DROP TABLE #Data

c # пример выполненияИП:

SqlCommand GetMaxCmd = new SqlCommand("sp_GetMaximumAvg", SQLConnection);
GetMaxCmd.CommandType = System.Data.CommandType.StoredProcedure;
GetMaxCmd.Parameters.Add("@FromDate", SqlDbType.DateTime).Value =     DateTime.Parse(from_date);
GetMaxCmd.Parameters.Add("@ToDate", SqlDbType.DateTime).Value = DateTime.Parse(to_date);
GetMaxCmd.Parameters.Add("@TableName", SqlDbType.VarChar).Value = table_name;

SqlParameter Output = GetMaxCmd.Parameters.Add("@MyOutput", SqlDbType.SmallInt);
Output.Direction = ParameterDirection.ReturnValue;

try
{
    GetMaxCmd.ExecuteNonQuery();
    Max = Convert.ToInt32(Output.Value);
}
catch (NullReferenceException) { }
catch (FormatException) { }
catch (SqlException) { }

1 Ответ

2 голосов
/ 20 мая 2011

Вы можете вызвать NextResult() в DataReader, чтобы получить набор результатов последовательных выборов.

РЕДАКТИРОВАТЬ: Вы можете return это вместо набора строк:

CLOSE read_cursor;
DEALLOCATE read_cursor;

RETURN (SELECT MAX(Result) AS MaxVar from @Result)

Это закончится параметром с направлением System.Data.ParameterDirection.ReturnValue.

Или вы могли бы прочитать это с SqlCommand.ExecuteScalar().

...