我在Microsoft SQL Server数据库中有一个存储过程:
USE [ProjectIndexer]
GO
/****** Object: StoredProcedure [files].[add_file] Script Date: 12/12/2014 1:34:20 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [files].[add_file]
@FILENAME varchar(255),
@EXTENSION nvarchar(8),
@PATH_FULL varchar(255),
@RELATIVE_PATH varchar(255),
@JOB varchar(15),
@DATE_MODIFIED datetimeoffset(7),
@SIZE BIGINT,
@INDEX_MODULE INT,
@FILE_TYPE varchar(255),
@DOC_TYPE varchar(255),
@DISCIPLINE varchar(255)
AS
DECLARE @file_id sql_variant
--Insert values for new file
INSERT INTO files.GENERAL
(FILENAME, EXTENSION, PATH_FULL, RELATIVE_PATH, JOB, DATE_MODIFIED, SIZE, INDEX_MODULE, FILE_TYPE, DOC_TYPE, DISCIPLINE)
VALUES(@FILENAME, @EXTENSION, @PATH_FULL, @RELATIVE_PATH, @JOB, @DATE_MODIFIED, @SIZE, @INDEX_MODULE, @FILE_TYPE, @DOC_TYPE, @DISCIPLINE);
--Get the ID of this new file
SELECT @file_id = current_value FROM sys.sequences WHERE name = 'FILE_ID_SEQ';
--Return ID
RETURN CONVERT(bigint, @file_id)
我正在尝试使用表适配器在Visual Studio 2012中开发的VB应用程序中运行此过程:
Dim myFilesGeneralTableAdapter As New FILES_GeneralTableAdapter
Dim FileID As Int32
FileID = myFilesGeneralTableAdapter.AddFile(FileName, fileExtension, foundFile, fileRelativePath, JobNumber, fileDateModified, fileSize, Nothing, Nothing, Nothing, Nothing)
由于某种原因,该函数没有将值返回给VB变量'FileID'。但是,我可以使用数据集设计器中的“预览数据”功能在Visual Studio中插入上述参数的值,在该环境中我可以获得返回值。
这告诉我,我的VB模块中的语法是错误的。谁能告诉我错误是什么?
答案 0 :(得分:0)
您是否考虑过使用System.Data.SqlClient.SqlCommand?您可以使用它来调用存储过程,添加参数值,并以检索单个值的方式执行它,即
Try
'Create command'
Dim command As New SqlCommand
command.CommandType = CommandType.StoredProcedure
conn = New SqlConnection(myConnString)
command.Connection = conn
command.CommandText = "add_file"
command.Parameters.AddWithValue("@Filename", [Filename])
...
command.Parameters.AddWithValue("@Discipline", Discipline)
command.Connection.Open()
Dim i As Int64 = command.ExecuteScalar()
command.Connection.Close()
'returns record ID'
Return i
Catch ex As Exception
Throw ex
Finally
If conn.State <> ConnectionState.Closed Then
conn.Close()
End If
End Try
请注意,在此示例中,“myConnString”是一个String,其值为我正在连接的数据库的连接字符串。
答案 1 :(得分:0)
我采用了将脚本转换为Entity Framework模型的好建议。起初,存储过程没有返回我想要的东西(它只返回1的整数值),但是我在网上发现了一个资源,指示我创建一个&#34;函数导入&#34;在EF模型中。执行此操作并正确匹配变量类型后,我设法让存储过程在Visual Studio中返回正确的值。这是一个很好的资源:
http://www.devtoolshed.com/using-stored-procedures-entity-framework-scalar-return-values
答案 2 :(得分:0)
在从TableAdapter
转换为实体框架之外(无论如何都是一个好的举动),您可以更好地返回OUTPUT
参数或结果集中的值。存储过程返回值实际上是为了传达操作的状态代码,因此非常有限。
此外,通过在INSERT
之后执行以下操作(即作为单独的步骤),
--Get the ID of this new file
SELECT @file_id = current_value FROM sys.sequences WHERE name = 'FILE_ID_SEQ';
如果某个其他进程几乎同时插入该表(即在此特定INSERT
和此特定SELECT
之间),则您可能会冒错误值。
考虑到上述两个问题,在INSERT
语句中使用OUTPUT子句会相当简单,而且非常可靠:
--Insert values for new file
INSERT INTO files.GENERAL
(FILENAME, EXTENSION, PATH_FULL, RELATIVE_PATH, JOB, DATE_MODIFIED, SIZE,
INDEX_MODULE, FILE_TYPE, DOC_TYPE, DISCIPLINE)
OUTPUT INSERTED.FILE_ID
VALUES(@FILENAME, @EXTENSION, @PATH_FULL, @RELATIVE_PATH, @JOB, @DATE_MODIFIED,
@SIZE, @INDEX_MODULE, @FILE_TYPE, @DOC_TYPE, @DISCIPLINE);
这将生成1行1列结果集。该列将被命名为FILE_ID
或任何实际字段名称(我猜这是基于用于其他字段和变量的命名约定)。
然后摆脱DECLARE @file_id
,SELECT ...
和RETURN ...
。