J'ai la procédure stockée suivante et quand j'essaye de faire fonctionner l'importation, elle dit que ma procédure stockée ne renvoie aucune colonne. Qu'est-ce que je rate? Aucune suggestion?
Le Proc:
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
CREATE TABLE #T
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
)
SET @SQL = '
INSERT #T
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
EXEC(@SQL)
SELECT ID, VendorName, ItemName, Type FROM #T
Essayez d’ajouter cette ligne au début de votre procédure stockée:
SET FMTONLY OFF
Vous pouvez le supprimer une fois l'importation terminée.
Qu'est-ce qui se passe ici dans les coulisses?
Lors de l’importation de fonctions -> Obtenir des informations sur la colonne ... Visual Studio exécute la procédure stockée avec toutes les valeurs param définies comme NULL (vous pouvez le vérifier par l’intermédiaire de MS SQL Profiler).
En effectuant l'étape 1, les colonnes résultantes de la procédure stockée sont renvoyées avec leur type de données et leurs informations de longueur.
Une fois les informations de la colonne extraites, cliquez sur le bouton 'Créer un nouveau type de complexe' pour créer le type de complexe du SP en conflit.
Dans votre cas, les paramètres proc stockés ne peuvent pas être annulés. Par conséquent, l'appel de Visual Studio échoue et ne renvoie aucune colonne.
Comment gérer ça?
SI (1 = 0) COMMENCER SET FMTONLY OFF si @ param1 est null et que @ param2 est null, alors commencer sélectionner cast (null comme varchar (10)) comme Column1, cast (null as bit) comme Column2, cast (null comme décimal) comme Column3 END END
Pour être précis (dans votre cas):
SI (1 = 0) COMMENCER SET FMTONLY OFF si @SearchString est null, alors COMMENCER sélectionner cast (null as int) en tant qu'ID, cast (null en tant que varchar (255)) en tant que VendorName, cast (null en tant que varchar (255)) en tant que ItemName, cast (null comme varchar (2)) comme Type END END
en complétant et en faisant simple @benshabatnoam, il suffit de mettre le code suivant au début:
IF (1=2)
SET FMTONLY OFF
Remarque: cela fonctionne dans EF 6.1.3 et Visual Studio 2015 Update 3.
Vous avez ce problème en raison de la table temporaire . Tout ce que vous avez à faire est: 1. Modifiez votre procédure stockée pour renvoyer le statemant sélectionné sans la table temporaire . 2. Allez dans la fonction import et obtenez les informations sur la colonne . 3. Modifiez votre procédure stockée de nouveau à l'original.
Pour que EF trouve les colonnes rapidement et correctement, commentez la clause where dans votre procédure stockée (ajoutez éventuellement un TOP 1 pour l’empêcher de tout renvoyer), ajoutez le processus à EF et créez le type complexe, puis décommentez le où clause à nouveau.
J'aimerais ajouter quelque chose à la réponse de Sudhanshu Singh: cela fonctionne très bien, mais si vous avez des structures plus complexes, combinez-le avec une déclaration de table.
J'ai utilisé avec succès les éléments suivants (placez-le au tout début de votre procédure stockée):
CREATE PROCEDURE [EY].[MyStoredProc]
AS
BEGIN
SET NOCOUNT ON;
IF (1=0)
BEGIN
SET FMTONLY OFF
BEGIN
-- declaration + dummy query
-- to allow EF obtain complex data type:
DECLARE @MyStoredProcResult TABLE(
ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
);
SELECT * FROM @MyStoredProcResult WHERE (1=0)
END
END
-- your code follows here (SELECT ... FROM ...)
-- this code must return the same columns/data types
--
-- if you require a temp table / table variable like the one above
-- anyway, add the results during processing to @MyStoredProcResult
-- and then your last statement in the SP can be
-- SELECT * FROM @MyStoredProcResult
END
Remarque que le 1=0
garantit qu'il n'est jamais exécuté, mais que l'EF en déduit la structure.
Après avoir enregistré votre procédure stockée, ouvrez le fichier EDMX dans Visual Studio, actualisez le modèle de données, accédez au navigateur de modèles Entity Frameworks. Dans le navigateur de modèle, localisez votre procédure stockée, ouvrez la boîte de dialogue "Éditer une importation de fonction", sélectionnez "Renvoie une collection de ... Complexe", puis cliquez sur le bouton "Obtenir les informations sur la colonne".
Il devrait montrer la structure telle que définie ci-dessus. Si tel est le cas, cliquez sur "Créer un nouveau type de complexe" pour en créer un avec le nom de la procédure stockée, par exemple. "MyStoredProc_Result" (ajouté par "_Result").
Vous pouvez maintenant le sélectionner dans la liste déroulante de "Renvoie une collection de ... Complex" dans la même boîte de dialogue.
Chaque fois que vous devez mettre à jour quelque chose, commencez par mettre à jour le SP, puis vous pourrez revenir à la boîte de dialogue Éditer une fonction d'importation et cliquer sur le bouton "Mettre à jour" (vous n'avez pas besoin de tout recréer de nouveau).
Si vous utilisez une table temporaire, l'entité (EDMX) ne peut pas comprendre ce qui se passe.
Donc, renvoyez le résultat vide avec le nom de la colonne, commentez toutes vos procédures stockées et exécutez-le dans le gestionnaire SQL, puis récupérez le type complexe dans visual studio. Après l'enregistrement, rétablissez l'état initial de votre procédure stockée (c'est-à-dire sans commentaire).
bonne chance/
J'ai eu ce problème, ce que je devais faire était de créer un type de table défini par l'utilisateur et de le renvoyer.
CREATE TYPE T1 AS TABLE
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
);
GO
Votre procédure stockée va maintenant ressembler à ceci:
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
@T [schema].T1
SET @SQL = 'SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
INSERT INTO @T
EXEC(@SQL)
SELECT ID, VendorName, ItemName, Type FROM @T
Il suffit d’ajouter l’instruction select sans la citation, d’exécuter le proc stocké, de mettre à jour le modèle, d’éditer l’importation de votre fonction et d’obtenir des informations sur les colonnes. Cela devrait remplir les nouvelles colonnes. Mettez à jour le jeu de résultats, revenez à votre procédure stockée et supprimez la liste de sélection que vous venez d'ajouter. Et exécutez le proc stocké. De cette façon, vos colonnes seront renseignées dans le jeu de résultats . Voir ci-dessous où ajouter la liste de sélection sans guillemets.
ALTER PROCEDURE [healthc].[ev_kc_Products_Search]
(
@SearchString VARCHAR(1000)
)
AS
SET NOCOUNT ON;
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
DECLARE @SQL VARCHAR(max),
@SQL1 VARCHAR(max),
@Tag VARCHAR(5)
CREATE TABLE #T
( ID INT,
VendorName VARCHAR(255),
ItemName VARCHAR(255),
Type VARCHAR(2),
Sequence TINYINT
)
SET @SQL = '
INSERT #T
SELECT VendorID ID,
Name VendorName,
NULL ItemName,
''V'' Type,
0 Sequence
FROM tblVendors
WHERE '+REPLACE(@SQL1,@Tag,'Name')+'
UNION ALL
BLAH BLAH BLAH'
EXEC (@SQL)
SELECT ID, VendorName, ItemName, Type FROM #T
J'espère que cela aide quelqu'un là-bas.