码迷,mamicode.com
首页 > 其他好文 > 详细

使用Microsoft.Practices.EnterpriseLibrary.Data调用存数过程Output参数注意事项

时间:2014-08-03 22:57:46      阅读:492      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   os   io   数据   for   

最近拿了一个开源的源码看了下,在调试的过程中发现调用存数过程的output参数的时候一直出错,现在将问题记录下来。

问题描述:

1. 使用Microsoft.Practices.EnterpriseLibrary.Data.dll调用数据库

2. 存数过程如下:

USE [Survey]
GO
/****** Object:  StoredProcedure [dbo].[vts_spQuestionCopy]    Script Date: 08/03/2014 19:11:10 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
/*
/// <summary>
/// Copy an existing question to another survey
/// </summary>
*/
ALTER PROCEDURE [dbo].[vts_spQuestionCopy]
                @QuestionID int, 
                @NewSurveyID int,
                @DisplayOrder int,
                @PageNumber int,
                @QuestionCopyID int output
AS

BEGIN TRANSACTION CopyQuestion

INSERT INTO vts_tbQuestion  
    (ParentQuestionId, 
    SurveyID,
    LibraryID,
    SelectionModeId, 
    LayoutModeId, 
    DisplayOrder,
    PageNumber, 
    MinSelectionRequired, 
    MaxSelectionAllowed, 
    RatingEnabled,
    ColumnsNumber,
    RandomizeAnswers,
    QuestionText,
    QuestionPipeAlias,
    QuestionIDText,
    HelpText,
    Alias,
    QuestiongroupID,
    ShowHelpText)
SELECT      
    ParentQuestionId, 
    @NewSurveyID,
    null, 
    SelectionModeId, 
    LayoutModeId, 
    @DisplayOrder,
    @PageNumber, 
    MinSelectionRequired, 
    MaxSelectionAllowed, 
    RatingEnabled,
    ColumnsNumber,
    RandomizeAnswers,
    QuestionText,
    QuestionPipeAlias,
    QuestionIDText,
    HelpText,
    Alias,
    QuestionGroupID,
    ShowHelpText
FROM vts_tbQuestion WHERE QuestionId = @QuestionID

-- Check if the cloned question was created
IF @@rowCount <> 0
BEGIN
    -- Clone the questions answers
    set @QuestionCopyID = convert(int,Scope_Identity())
    INSERT INTO vts_tbMultiLanguageText(LanguageItemID, LanguageCode, LanguageMessageTypeID, ItemText)
        SELECT @QuestionCopyID as LanguageItemID, LanguageCode, LanguageMessageTypeID, ItemText
        FROM vts_tbMultiLanguageText
        WHERE LanguageItemID = @QuestionID AND LanguageMessageTypeID in(3,10,11,12)    

    exec vts_spQuestionChildsClone @QuestionID, @QuestionCopyID, @NewSurveyID
    UPDATE vts_tbQuestion SET DisplayOrder = @DisplayOrder, PageNumber = @PageNumber 
    WHERE SurveyID = @NewSurveyID AND ParentQuestionid = @QuestionCopyID

    exec vts_spAnswersCloneByQuestionId @QuestionID, @QuestionCopyID

    exec vts_spQuestionSectionOptionClone @QuestionID, @QuestionCopyID

    -- Update the display order
    UPDATE vts_tbQuestion 
    SET DisplayOrder = DisplayOrder + 1 
    WHERE 
        SurveyID = @NewSurveyID AND
        ((QuestionID<>@QuestionCopyID AND ParentQuestionID is null) OR
         (ParentQuestionID is not null AND ParentQuestionID <> @QuestionCopyID)) AND
         DisplayOrder >= @DisplayOrder
END

COMMIT TRANSACTION CopyQuestion

3. 代码中的调用过程如下:

        public int CopyQuestionById(int questionId, int targetSurveyId, int targetDisplayOrder, int targetPageNumber)
        {
            //SqlParameter[] commandParameters = new SqlParameter[] 
            //{ new SqlParameter("@QuestionId", questionId), 
            //    new SqlParameter("@NewSurveyId", targetSurveyId), 
            //    new SqlParameter("@DisplayOrder", targetDisplayOrder), 
            //    new SqlParameter("@PageNumber", targetPageNumber), 
            //    new SqlParameter("@QuestionCopyId", SqlDbType.Int) 
            //};
            //commandParameters[4].Direction = ParameterDirection.Output;

            ArrayList commandParameters = new ArrayList();
            {
                commandParameters.Add(new SqlParameter("@QuestionId", questionId).SqlValue);
                commandParameters.Add(new SqlParameter("@NewSurveyId", targetSurveyId).SqlValue);
                commandParameters.Add(new SqlParameter("@DisplayOrder", targetDisplayOrder).SqlValue);
                commandParameters.Add(new SqlParameter("@PageNumber", targetPageNumber).SqlValue);
                commandParameters.Add(new SqlParameter("@QuestionCopyId", SqlDbType.Int) { Direction = ParameterDirection.Output}.SqlValue);
            }

            DbConnection.db.ExecuteNonQuery("vts_spQuestionCopy", commandParameters);
            return int.Parse(commandParameters[4].ToString());
        }

 

咱们来分析一下这段代码:在调用的使用一直提示一个错误

new SqlParameter("@QuestionCopyId", SqlDbType.Int) { Direction = ParameterDirection.Output}.SqlValue

为空。原来当为Output时,sqlvalue就会为空,现在我们应该怎么办呢?

我尝试给其一个默认值,将代码修改为

new SqlParameter("@QuestionCopyId", SqlDbType.Int) { Direction = ParameterDirection.Output, Value = 0}.SqlValue

新的问题出现了:

 An exception of type ‘System.InvalidOperationException‘ occurred in Microsoft.Practices.EnterpriseLibrary.Data.dll but was not handled in user code

Additional information: The number of parameters does not match number of values for stored procedure. 

ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)

这个错误是什么意思呢?意思是说参数个数不一致。查询后得知,原来 params 传的是值,当Output有默认值的时候,传入参数就为5个,可是存储过程只接受4个。现在应该怎么办呢?

尝试修改

DbConnection.db.ExecuteNonQuery("vts_spQuestionCopy", commandParameters.ToArray());

但是还是会报错,同样的错误。尝试去掉默认值,使用上述方法,成功运行,但是想取到返回值就懵了,取不到。肿么办?

 

尝试使用ExecuteNonQuery(DbCommand command),将代码修改如下:

        public int CopyQuestionById(int questionId, int targetSurveyId, int targetDisplayOrder, int targetPageNumber)
        {
            SqlParameter[] commandParameters = new SqlParameter[] 
            { new SqlParameter("@QuestionId", questionId), 
                new SqlParameter("@NewSurveyId", targetSurveyId), 
                new SqlParameter("@DisplayOrder", targetDisplayOrder), 
                new SqlParameter("@PageNumber", targetPageNumber), 
                new SqlParameter("@QuestionCopyId", SqlDbType.Int) 
            };
            commandParameters[4].Direction = ParameterDirection.Output;

            SqlCommand vts_spQuestionCopy = new SqlCommand("vts_spQuestionCopy");
            vts_spQuestionCopy.CommandType = CommandType.StoredProcedure;
            vts_spQuestionCopy.Parameters.AddRange(commandParameters);
            DbConnection.db.ExecuteNonQuery(vts_spQuestionCopy);

            var result =int.Parse(vts_spQuestionCopy.Parameters["@QuestionCopyID"].Value.ToString());
            return result;
        }

运行成功,取到output返回值。

 

Note:ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)中的params其实是将SqlParameter中的值传入。想要取到output返回值的时候,可能会存在问题。目前我是使用ExecuteNonQuery(DbCommand command)来得到返回值,各位如果有其它方法,敬请留下,谢谢。

 

使用Microsoft.Practices.EnterpriseLibrary.Data调用存数过程Output参数注意事项,布布扣,bubuko.com

使用Microsoft.Practices.EnterpriseLibrary.Data调用存数过程Output参数注意事项

标签:style   blog   color   使用   os   io   数据   for   

原文地址:http://www.cnblogs.com/aaronday/p/3888909.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!