2017-10-07 11 views
2
ALTER PROCEDURE [dbo].[ProcTeamInfoById] 
    (@id INT, 
    @txtName VARCHAR(50), 
    @phone VARCHAR(100), 
    @contactname VARCHAR(100),      
    @address VARCHAR(300), 
    @email VARCHAR(100), 
    @captain VARCHAR(100), 
    @requirements VARCHAR(50)) 
AS      
BEGIN 
    IF @id = -1      
    BEGIN 
     DECLARE @teamID VARCHAR(MAX); 

     INSERT INTO TeamDetails(TeamName, Phone, ContactName, Address, Email, captain)    
     VALUES (@txtName, @phone, @contactname, @address, @email, @captain)  

     SET @teamID = SCOPE_IDENTITY();  

     // Here now I need to add to different table... 

     // checkbox checked values 

     INSERT INTO teamrequirements (teamid, requirement, value) 
     VALUES (@teamID, @requirements, 1) 

     // Here I am getting 1, bats, Gloves, 1 
    END 
    ELSE 
     UPDATE TeamDetails 
     SET TeamName = @txtName, Phone = @phone, 
      ContactName = @contactname,      
      Address = @address, Email = @email, 
     WHERE TeamId = @id 
    END 

J'ai besoin comme celui-ci comment modifier la procédure stockéeComment diviser une seule valeur de la ligne et l'insérer dans plusieurs colonnes en utilisant la procédure stockée, la valeur du paramètre est de C#

1, bats,gloves,1 

Je dois ajouter que

1 bats 1 
2 gloves1 

Si je dois mettre à jour ce qui précède, il devrait être comme

1 bats 1 

Si je mise à jour sans valeurs qu'il devrait être comme

1 '' '' 

Ma procédure stockée insère dans deux tables. Tout en ajoutant dans le tableau teamrequirements, j'ai besoin de diviser une valeur de colonne en plusieurs colonnes où j'ai commenté. J'ai besoin de modifier la procédure stockée pour insérer dans plusieurs colonnes et enregistre dans le tableau teamrequirements.

Comment le faire? Lors de l'ajout d'une équipe dans le tableau teamdetails, j'ai coché la case Exigences si je coche la case Je peux cocher deux autres cases, lorsque les deux cases à cocher sont cochées, deux enregistrements à insérer dans les exigences de l'équipe, par exemple, iwil ont teamid, exigence, valeur ... l'exemple 1, battes, gants, 1, doit insérer comme 2 disques comme

12,1 bat , 1 // 12 is record id in teamrequirements 
13,1,Gloves , 1 // 13 is record id in teamrequirements 

S'il vous plaît aider ...

si elle est mise à jour dans la même procédure. mise à jour teamrequirements set exigence = @reuirement, valeur = 1 où teamid = @id dans th est le cas, si j'ajoute ces deux dossiers bats gants dans la base de données j'ajoute des enregistrements, et si je dois effacer ces enregistrements ajoutés en utilisant la déclaration de mise à jour dans la même procédure

+3

La question est difficile à comprendre, mais il semble que vous avez besoin de re-conception comment les exigences est construit. Il semble que @Requirements devrait être un paramètre de valeur table (terme utilisable sur Google) qui a une ligne pour chaque exigence. – Crowcoder

+0

Lors de l'ajout d'une équipe, l'équipe est ajoutée dans la table des détails, et j'ai une case à cocher comme Exigences si je peux cocher deux autres cases, lorsque les deux cases sont cochées, deux entrées à insérer dans l'équipe, par exemple , exigence, valeur ... exemple 1, chauves-souris, Gants, 1 ceci devrait être inséré comme 2 enregistrements .. – Jones

+1

Cela ne me l'explique pas vraiment, mais maintenant je pense que vous devez juste diviser '@ Requirements' en variables nullables séparées. Quoi qu'il en soit, il semble clair que «@ Requirements» n'est pas approprié pour communiquer ce dont vous avez besoin dans votre procédure. – Crowcoder

Répondre

1

Vous pouvez utiliser l'un des split function over the internet or create your own et l'utiliser. Le code ci-dessous a été écrit en fonction de la fonction de division dans FnSplitString.

Vous avez créé une fonction de division dans votre base de données. Cette fonction retournera 1 ou plusieurs valeurs de votre chaîne fournie. Ceci est votre variable @requirements.

IF(LEN(@requirements) > 0) 
BEGIN 

    INSERT INTO teamrequirements (teamid, requirement, value) 
    SELECT @teamID, splitdata, '1' FROM dbo.[fnSplitString](@requirements,',') 
END 
ELSE 
BEGIN 
    INSERT INTO teamrequirements (teamid, requirement, value) 
    VALUES (@teamID, '', '') 
END 

SQL 2016:

JSON support est là maintenant. Ainsi, vous pouvez passer une chaîne comme json et prendre 2 valeurs dans la table de valeur de clé, et l'insérer directement. Pas besoin de se séparer.

POUR MISE À JOUR: Vous pouvez prendre cette donnée de chaîne fractionnée dans une variable de table. Mettez à jour les données de la variable table en tant que source dans la table principale, avec une condition JOIN.

DECLARE @id INT = 40 

DECLARE @data TABLE 
(
Id INT, 
Requirement VARCHAR(50), 
Value INT 
) 

DECLARE @requirements VARCHAR(50) = 'bat,gloves,ball' 
INSERT INTO @data 
SELECT @id, splitdata, 1 FROM dbo.[fnSplitString](@requirements,',') 

SELECT * FROM @data 

-- SOMETHING LIKE THIS CAN BE YOUR UPDATE QUERY 
UPDATE a SET 
value = b.Value 
FROM teamrequirements a INNER JOIN @data b ON a.id = b.Id 
and a.requirement = b.Requirement 

EXEMPLE MERGE:

MERGE teamrequirements AS TARGET 
USING @data AS SOURCE 
ON TARGET.id = SOURCE.Id AND TARGET.requirement = SOURCE.Requirement 
--When records are matched, update 
--the records if there is any change 
WHEN MATCHED THEN 
UPDATE SET TARGET.value = SOURCE.Value 
--When no records are matched, insert 
--the incoming records from source 
--table to target table 
WHEN NOT MATCHED BY TARGET THEN 
INSERT (teamid, requirement, value) 
VALUES (SOURCE.Id, SOURCE.Requirement, SOURCE.Value); 
+0

Pouvons-nous arrêter de conseiller aux gens de séparer les chaînes quand nous avons été capables de le faire correctement depuis SQL 2005? – Crowcoder

+0

@Crowcoder Son cas d'utilisation est comme ceci. Sinon, il ne devrait pas apporter plusieurs données dans une variable. Mieux utiliser le type de données XML dans ce cas, ou créer son propre type de table. Mais actuellement, sa question et son cas d'utilisation sont tels. – Amit

+0

En outre, les deux "lignes" sont dans la même chaîne, ce qui nécessiterait un T-SQL supplémentaire gênant pour les supprimer. – Crowcoder

0

En premier lieu, il serait préférable d'utiliser la table des paramètres évalués pour cela. Sans cela, vous pouvez fractionner la chaîne (cette démo utilise delimitedsplit8k de Jeff Moden), et vous pouvez utiliser merge pour gérer les changements. Il est logique de déplacer ceci dans sa propre procédure et appelez cette procédure de votre actuelle.

TL; DR: rextester demo: http://rextester.com/PVX88970

La procédure TeamRequirements_Merge:

create procedure dbo.TeamRequirements_Merge (
    @TeamId int 
    , @requirements varchar(8000) 
) as 
begin; 
    set nocount, xact_abort on; 
    /* it would be much better to use table valued parameters for this */ 
    ;with t as (
    select TeamId, Requirement, Value 
    from TeamRequirements 
    where TeamId = @TeamId 
) 
    , s as (
    select 
     TeamId = @TeamId 
     , Requirement = coalesce(s.item,'') -- since you want blanks 
     , Value = 1 
    from dbo.[delimitedsplit8K](@requirements,',') s 
) 
    merge into t with (holdlock) 
    using s 
    on t.TeamId = s.TeamId 
    and t.Requirement = s.Requirement 
    when matched and t.value <> s.value 
    then update set t.value = s.value 
    when not matched by target 
    then insert (TeamId, Requirement, Value) 
     values (s.TeamId, s.Requirement, s.Value) 
    when not matched by source 
    then delete 
    --output $Action, inserted.*, deleted.* /* for testing */ 
    ; 
end; 
go 

La procédure ProcTeamInfoById révisé:

create procedure [dbo].[ProcTeamInfoById] (
    @id int 
    , @txtName varchar(50) 
    , @phone varchar(100) 
    , @contactname varchar(100) 
    , @address varchar(300) 
    , @email varchar(100) 
    , @captain varchar(100) 
    , @requirements varchar(8000) 
) as 
begin; 
    if @id = -1 
    begin; 
     insert into TeamDetails(TeamName, Phone, ContactName, Address, Email, captain) 
     values (@txtName, @phone, @contactname, @address, @email, @captain); 

     set @id = scope_identity(); 
    end; 
    else 
    begin; 
     update TeamDetails 
     set TeamName = @txtName, Phone = @phone, 
      ContactName = @contactname, 
      Address = @address, Email = @email 
     where TeamId = @id; 
    end; 
    exec dbo.TeamRequirements_Merge @id, @requirements; 
end; 
go 

chaînes de fractionnement référen ce:

merge référence:


Encore une fois, il serait préférable d'utiliser la table des paramètres évalués pour cela:

Tableau Valued Paramètres Référence:

+0

Merci pour la réponse.je peux obtenir la modification pour l'insertion des enregistrements et la mise à jour des mêmes enregistrements. – Jones

+0

@jones cela fait déjà cela, comme indiqué dans la démo. Est-ce que je comprends mal ce que vous voulez dire? – SqlZim

+0

désolé je n'ai pas testé..exemple. tout en insérant 1, les chauves-souris, les gants, l'argent, 1 devrait être enregistré comme // 1 chauves-souris 1, 1, gants, 1, 1, argent, 1 ..1 est id d'équipe et 1 est vrai vrai .. les mêmes enregistrements si je vouloir mettre à jour comme 1, '', 0 bases sur recordid stocké dans la table db teamrequirements – Jones