2016-10-27 2 views
1

Я запускаю хранимую процедуру, возвращающую результат COUNT на огромном SELECT.Извлечение хранимой процедуры COUNT из DataSet в C#

В результате я обнаружил, что у меня есть DataSet в коде C#, но после многочисленных попыток я не смог извлечь результат COUNT.

Вот мой код, вы можете игнорировать длительную хранимую процедуру. В конце концов это всего лишь COUNT (*), но это на всякий случай.


C# Код:

internal int ObtenirCount(string ProcedureName, IConnexionBD _ConnexionBD, params SqlParameter[] parametres) 
{ 
    int count = 0; 
    IConnexionBD _ConnBd = _ConnexionBD ?? new ConnexionBD(ObtenirChaineDeConnexion()); 

    DataSet ds = _ConnBd.ExecuteDataSet(string.Format(ProcedureName, NomTable), parametres); 

    if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 
    { 
     count = ds.Tables[0].Rows.Count; // Doesn't work 
    } 
    return count; 
} 

хранимых процедур:

ALTER PROCEDURE [dbo].[PSS_us_net_010] 
@PageSize int, 
@PageNumber int, 
@filtreType varchar, 
@filtrePrincipal varchar, 
@filtreNumUtilisateur varchar, 
@filtreNom varchar, 
@filtreCourriel varchar, 
@filtreCompteCentral varchar, 
@sortColumnUser varchar 

AS 

DECLARE @Sort char(35) 
DECLARE @StartRow int 
DECLARE @strFiltreType varchar(100) = '' 
DECLARE @strFiltrePrincipal varchar(100) = '' 
DECLARE @strFiltreNumUtilisateur varchar(100) = '' 
DECLARE @strFiltreNom varchar(100) = '' 
DECLARE @strFiltreCourriel varchar(100) = '' 
DECLARE @strFiltreCompteCentral varchar(100) = '' 
DECLARE @strSortColUser varchar(100) = '' 

SET @StartRow = CAST(((@PageNumber - 1)*@PageSize + 1) AS varchar(50)) 
IF @filtreType != '' 
    BEGIN 
     SET @strFiltreType = @filtreType 
    END 
IF @filtrePrincipal != '' 
    BEGIN 
    IF @filtrePrincipal = 'o' OR @filtrePrincipal = 'u' OR @filtrePrincipal = 'i' OR @filtrePrincipal = 'ou' OR @filtrePrincipal= 'oui' OR @filtrePrincipal = 'ui' 
     SET @strFiltrePrincipal = 00 
    ELSE 
     SET @filtrePrincipal = NULL 
    END 
IF @filtreNumUtilisateur != '' 
    BEGIN 
     SET @strFiltreNumUtilisateur = @filtreNumUtilisateur 
    END 
IF @filtreNom != '' 
    BEGIN 
     SET @strFiltreNom = @filtreNom 
    END 
IF @filtreCourriel != '' 
    BEGIN 
     SET @strFiltreCourriel = @filtreCourriel 
    END 
IF @filtreCompteCentral != '' 
    BEGIN 
     SET @strFiltreCompteCentral = @filtreCompteCentral 
    END 
IF @sortColumnUser != '' 
    BEGIN 
     SET @strSortColUser = @sortColumnUser 
    END 

BEGIN 

    SELECT COUNT(*)FROM 
    (
    SELECT 
    ty_util_net, 
    ident_util_net, 
    no_usager_net, 
    nip, 
    nip_temporaire, 
    adr_courriel, 
    dte_creer, 
    dte_modif, 
    dte_dern_utilisation, 
    hre_dern_utilisation, 
    nb_visites, 
    nom_prenom, 
    dte_avant_dern_util, 
    hre_avant_dern_util, 
    adr_courriel_erronee, 
    phrase_mot_passe, 
    nom_navigateur, 
    version_navigateur, 
    date_env_courriel, 
    ChoixAucunePhrase, 
    EnvoiCourriel, 
    DetCCReg, 
    IndAffPhrase 
    FROM us_net 
    WHERE nom_prenom >= @Sort 
    AND(@filtreType IS NULL OR ty_util_net LIKE '%' + @strFiltreType + '%') 
    AND(@filtrePrincipal IS NULL OR no_usager_net LIKE '%' + @strFiltrePrincipal + '%') 
    AND(@filtreNumUtilisateur IS NULL OR ident_util_net LIKE '%' + @strFiltreNumUtilisateur + '%') 
    AND(@filtreNom IS NULL OR nom_prenom LIKE '%' + @strFiltreNom + '%') 
    AND(@filtreCourriel IS NULL OR adr_courriel LIKE '%' + @strFiltreCourriel + '%') 
) AS countResult 
END 
+1

Ваша хранимая процедура возвращает счет? И вы получаете доступ к Rows.Count? Это будет учитывать количество строк в вашем DataTable. Доступ к значению этого не подсчитывает строки. – Sebi

+1

не для чего предназначен ExecuteScaler? – JamieD77

+0

@Sebi Да, это ошибка новичка, я думаю, хе-хе. –

ответ

2

В результате этой хранимой процедуры в первой строке, первый столбец.
Свойство Rows.Count возвращают всегда 1 в этом контексте, поскольку его цель состоит в том, чтобы подсчитать количество строк, присутствующих в DataTable

Так что ваш код должен быть просто

count = Convert.ToInt32(ds.Tables[0].Rows[0][0]); 

Как было отмечено в комментариях, когда вам нужно только одно скалярное значение, такое как те, которые возвращаются с помощью COUNT, SUM или любого запроса с одной строкой/одним столбцом, вы должны подумать об использовании ExecuteScalar. Он намного эффективнее, потому что ему не нужно создавать DataSet, DataTables и всю инфраструктуру, необходимую для поддержки этих объектов.

+0

у вас отсутствует доступ к столбцу: p .Rows [0] [0] – Sebi

+0

ok исправлено быстрее, чем я набрал: D – Sebi

+1

Я пробовал count = Convert.ToInt32 (ds.Tables [0] .Rows [0] и cann ' t find.column after. Не думал, что это 2D-массив .. Ну, это все объясняет! Спасибо :) –

1

Если вы хотите использовать существующую реализацию, зачем использовать ds.Tables[0].Rows.Count?

Просто остановитесь на ds.Tables[0].Rows[0][0], это даст вам элемент в строке напрямую. Убедитесь, что вы конвертируете/отбрасываете. Поскольку хранимая процедура уже дает счет.

1
count = Convert.ToInt32(ds.Tables[0].Rows[0][0]); 

Вы должны попробовать это. потому что это будет первая первая таблица первой строки и первого столбца.

Я бы предложил лучше использовать ExecuteScalar или DatabaseExecuteScalar, если вы хотите получить только одно значение. DataSet является тяжелым. DataSet должен использоваться там, где мы должны получить данные в форме таблицы и нам нужно прочитать/написать DataSet.

+0

Я не знал о существовании ExecuteScalar, я как бы новый для SQL. Я посмотрю на это спасибо! –