.net - stored - procedimientos almacenados en java netbeans
¿Cómo puede nombrar las tablas del conjunto de datos que devuelve en un proceso almacenado? (16)
¿Hay alguna razón por la que no pueda nombrarlos manualmente después de llenar el DataSet?
mySqlDataAdapter.Fill(ds);
ds.Tables[0].TableName = "NametbA";
ds.Tables[1].TableName = "NametbB";
No conozco ninguna forma de nombrar los DataTables que se devuelven como parte de múltiples conjuntos de resultados de un procedimiento almacenado, pero si usted sabe qué devuelve el proceso almacenado, nombrarlos manualmente debería funcionar bien.
Editar
Sabiendo que tiene control sobre el procedimiento almacenado, una alternativa podría ser agregar una columna a los conjuntos de resultados que representa el nombre de la tabla. Entonces, podrías hacer algo como:
foreach (DataTable table in ds.Tables)
{
table.TableName = table.Rows[0]["TableName"].ToString();
}
Sin embargo, esto depende de que los conjuntos de resultados vuelvan de los procedimientos almacenados que realmente contienen filas. Si no contienen filas, tendrías que envolverlo en una declaración "if" y no todas las tablas obtendrían un nombre.
Tengo el siguiente procedimiento almacenado
Create procedure psfoo ()
AS
select * from tbA
select * from tbB
Entonces estoy accediendo a los datos de esta manera:
Sql Command mySqlCommand = new SqlCommand("psfoo" , DbConnection)
DataSet ds = new DataSet();
mySqlCommand.CommandType = CommandType.StoredProcedure;
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();
mySqlDataAdapter.SelectCommand = mySqlCommand;
mySqlDataAdapter.Fill(ds);
Ahora, cuando quiero acceder a mis tablas, tengo que hacer esto:
DataTable datatableA = ds.Tables[0];
DataTable datatableB = ds.Tables[1];
la propiedad Tablas del conjunto de datos también tiene un descriptor de acceso por cadena (en lugar de int).
¿Es posible? Especifique el nombre de las tablas en el código SQL, para que pueda escribir esto:
DataTable datatableA = ds.Tables["NametbA"];
DataTable datatableB = ds.Tables["NametbB"];
Estoy usando SQL Server 2008, si eso hace la diferencia.
Esta pregunta es antigua, pero está en la parte superior de la búsqueda de Google, jeje. Tal vez ayudará a alguien ...
Y la respuesta es sí, es posible especificar el nombre de las tablas en el código para que pueda acceder a DataTable en DataSet por su nombre.
Primero, debo explicar cómo funciona TableMapping. Si no especificamos TableMappings con SqlDataAdapter (SqlDataAdapter que llenará nuestro DataSet), de manera predeterminada, la primera tabla se denominará "Tabla", la segunda se denominará "Tabla1", la tercera se denominará "Tabla2", etc.
Entonces, cuando queremos llamar a DataTable en DataSet, lo usamos así:
//...
System.Data.DataSet myDataSet = new System.Data.DataSet();
using (System.Data.SqlClient.SqlDataAdapter dbAdapter = new System.Data.SqlClient.SqlDataAdapter(dbCommand))
{
dbAdapter.TableMappings.Add("Table", "MyFirstTitleForTableOne");
dbAdapter.TableMappings.Add("Table1", "MyFirstTitleForTableTwo");
dbAdapter.TableMappings.Add("Table2", "MyFirstTitleForTableThree");
dbAdapter.TableMappings.Add("Table3", "MyFirstTitleForTableFour");
//...
dbAdapter.Fill(myDataSet);
}
//...
Y, ahora podemos acceder a DataTable por nuestro título:
System.Data.DataTable firstTable = myDataSet.Tables["MyFirstTitleForTableOne"];
System.Data.DataTable secondTable = myDataSet.Tables["MyFirstTitleForTableTwo"];
Lo siento, pero no escribí código que verificará null (myDataSet) o lo configuré en el bloque try / catch porque creo que no es irrelevante para esta pregunta.
Esto funciona para mí, pero necesita un trabajo adicional para obtener los nombres de tabla esperados:
Dim tableCount As Integer = 3
Dim tables(tableCount) As DataTable
tables(0) = (New DataTable("Employee"))
tables(1) = (New DataTable("Manager"))
tables(2) = (New DataTable("Department"))
dsUControlData.Tables.Add(tables(0))
dsUControlData.Tables.Add(tables(1))
dsUControlData.Tables.Add(tables(2))
''Fill required tables
da.Fill(0, 0, tables)
Return dsUControlData
Para dar nombres a todas las tablas en un conjunto de datos, necesitamos escribir una consulta de selección más al final del SP o T-Sql.
lsqry = New System.Text.StringBuilder
lsqry.AppendLine("select * from Bill_main")
lsqry.AppendLine("select * from serviceonly")
lsqry.AppendLine("select * from PendingService")
lsqry.AppendLine("select * from T_servicebillhd")
lsqry.AppendLine("select ''Bill_Main'',''serviceonly'',''PendingService'',''T_servicebillhd''")
Using con As New SqlConnection(lsConnection)
Try
con.Open()
Using cmd As SqlCommand = con.CreateCommand
With cmd
.CommandText = lsqry.ToString
.CommandType = CommandType.Text
End With
Using da As New SqlDataAdapter(cmd)
da.Fill(DS)
End Using
End Using
For li As Integer = 0 To DS.Tables.Count - 2
DS.Tables(li).TableName = DS.Tables(DS.Tables.Count - 1).Rows(0).Item(li)
Next
Catch ex As Exception
End Try
End Using
En el ejemplo anterior, estoy usando instrucción t-sql en lugar de SP. En el cual escribí 4 seleccionar consulta y el último es el nombre de la tabla de esas tablas. Y busque la última tabla que contiene nombres de tablas y asígnela a la tabla usando la propiedad TableName.
Podría devolver un conjunto de resultados adicional que nombre las tablas como esta:
SELECT ''firstTableName'' AS tbl
UNION
SELECT ''secondTableName'' AS tbl
UNION
...
Si ese fue el primer conjunto de resultados, podría usarlo para nombrar los conjuntos de resultados posteriores sobre la marcha.
Por lo que sé, del proceso almacenado, no puedes hacer eso. Sin embargo, puede establecer los nombres una vez que haya recuperado el DataSet y luego usarlos a partir de ese momento.
ds.Tables[0].TableName = "NametbA";
Procedimiento almacenado :
select ''tbA'',''tbB'',''tbC''
select * from tbA
select * from tbB
select * from tbC
Interfaz:
int i = 1;
foreach (string tablename in dsEmailData.Tables[0].Rows[0][0].ToString().Split('',''))
{
dsEmailData.Tables[i++].TableName = tablename;
}
Espero que esto ayude
Prueba esto
YourDataAdapter.Fill(ds, "Table");
Prueba esto. En MS SQL 2008 R2, siempre uso esto.
mySqlDataAdapter.Fill(ds,"NameTableA");
Puede ser que este sea el trabajo alrededor
Create procedure psfoo ()
AS
select * ,''tbA'' as TableName from tbA
select * ,''tbB'' as TableName from tbB
Luego, en el código C #
foreach (DataTable dt in ds.Tables)
{
if (dt.Rows[0]["TableName"].ToString().Contains("tbA"))
{
}
else if (dt.Rows[0]["TableName"].ToString().Contains("tbB"))
{
}
}
Puedes intentar esto:
agregue debajo de la línea en su procedimiento
Select ''TableName1'',''TableName2'';
Usando C #:
for (var i=0;i<ds.Tables[0].Columns.Count;i++)
{
ds.Tables[i + 1].TableName = ds.Tables[0].Columns[i].ColumnName;
}
Sé que esta es una publicación muy antigua, pero para responder ... Sí, es posible. Simplemente agregue el "TableName"
Nombre de tabla "TableName"
en el complemento de datos Fill
llamada ..
MyDataAdapter.Fill(ds, "TableName");
Soy un chico C #, pero entiendes el punto.
Sé que esta es una vieja pregunta, pero estaba pensando en hacer las mismas cosas hoy, así que no estaba simplemente recorriendo un índice del conjunto de datos de resultados. Porque si el procedimiento almacenado cambia por orden de seleccionar el código .net se disparará.
Se me ocurrió la solución de agregar una columna al conjunto de resultados con el nombre de la tabla y usar una declaración de caso para ver si la columna existe en la tabla. Pero parecía que estaba cambiando el código. Acabo de hacer el SQL estático. Además, ¿qué sucede si tiene una columna con el mismo nombre en una tabla diferente? Cojo...
myDS.Tables(i).Columns.Contains("TableName")
Tengo un proceso almacenado que accede a todos los datos en mi empresa y devuelve múltiples conjuntos de resultados. Tengo más sentido para mí hacer una selección con el nombre antes de cada conjunto de resultados. Al igual que:
SELECT ''Customers'' AS TableName
SELECT ID, Name FROM dbo.Customer
SELECT ''Orders'' AS TableName
SELECT ID, Created FROM dbo.[Order]
Luego, cuando itero sobre MyDataSet.Tables, solo tengo la lógica de búsqueda de un solo ciclo y directa. No hay una tabla maestra de metadatos para mantenerse al día. Esto incluso funciona cuando no se devuelven tablas. Si los datos de la tabla no se devuelven, los metadatos coincidentes no se devuelven, lo cual tiene sentido para mí.
For Each DataTable As DataTable In MyDataSet.Tables
MyDataSet.Tables(MyDataSet.Tables.IndexOf(DataTable) + 1).TableName = DataTable.Rows(0)("TableName")
Next
Si quiero agregar más columnas a las tablas de metadatos, puedo.
buena idea, es mejor que su procedimiento devuelva tres resultados en lugar de agregar el nombre de la tabla en
firs trow of each table
select ''tbA'' FirstTableName,''tbB'' SecondTableName
select * from tbA
select * from tbB
cada vez que ejecutas el procedimiento, las tablas [0] tendrán una fila que sigue de cerca seleccionando nombres de tablas
Otra idea puede ser pasar el nombre de la tabla como parámetro de salida de procedimiento
Create procedure psfoo (@tb1 varchar(50) output,@tb2 varchar(50) output)
AS
set @tb1=''tbA''
set @tb2 ''tbB''
select * from tbA
select * from tbB
Si este método te limita y selecciona una variable, puedes crear un procedimiento como este
Create procedure psfoo ()
AS
select * from tbA
select * from tbB
return ''tbA,tbB''
y al dividir el valor de recuperación del procedimiento en la cadena [], puede obtener el nombre de las tablas ordinalmente
[email protected](new char[]{'',''});
string tablenam1=returnvalue[0];
string tablenam2=returnvalue[1];
debería usar seleccionar en "yourtablename" de originaltable, esto es solo un ejemplo, encuentre la sintaxis correcta de select into en statement.
Esta es la forma correcta de hacerlo por su requerimiento. Gracias.