Username increment by 1 if already exist in mssql 2008 - sql-server

Create table TEMP_USER
(
USERNAME nvarchar(50) ,
ID int,
Phone nvarchar(30)
);
IF the user name already exist in temp_user it should incement by 1 while inserting through SP.
Example : RAM .Narayan if anyone trying to insert again ram.narayan it should insert as ram.narayan1 next time anyone trying to insert ram.narayan it should insert ram.narayan2 ..How to do this in MSSQL 2008

Try something like the following (untested, but it should give you a good start). It assumes the variables #username, #id, and #phone are already declared or passed as parameters.
DECLARE #curr_uname nvarchar(50) = #username
DECLARE #i INT = 0
WHILE EXISTS (SELECT 1 FROM TEMP_USER WHERE USERNAME = #curr_uname)
BEGIN
SET #i += 1
SET #curr_uname = #username + CAST(#i AS NVARCHAR(7))
END
INSERT INTO TEMP_USER (USERNAME, ID, Phone)
VALUES (#curr_uname, #id, #phone)

Related

How to get and use the value returned by a stored procedure to a INSERT INTO... SELECT... statement

I am just new in SQL language and still studying it. I'm having hard time looking for answer on how can I use the stored procedure and insert value into a table.
I have this stored procedure:
CREATE PROCEDURE TestID
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NewID VARCHAR(30),
#GenID INT,
#BrgyCode VARCHAR(5) = '23548'
SET #GenID = (SELECT TOP (1) NextID
FROM dbo.RandomIDs
WHERE IsUsed = 0
ORDER BY RowNumber)
SET #NewID = #BrgyCode + '-' + CAST(#GenID AS VARCHAR (30))
UPDATE dbo.RandomIDs
SET dbo.RandomIDs.IsUsed = 1
WHERE dbo.RandomIDs.NextID = #GenID
SELECT #NewID
END;
and what I'm trying to do is this:
INSERT INTO dbo.Residents([ResidentID], NewResidentID, [ResLogdate],
...
SELECT
[ResidentID],
EXEC TestID ,
[ResLogdate],
....
FROM
source.dbo.Resident;
There is a table dbo.RandomIDs containing random 6 digit non repeating numbers where I'm pulling out the value via the stored procedure and updating the IsUsed column of the table to 1. I'm transferring data from one database to another database and doing some processing on the data while transferring. Part of the processing is generating a new ID with the required format.
But I can't get it to work Sad I've been searching the net for hours now but I'm not getting the information that I need and that the reason for my writing. I hope someone could help me with this.
Thanks,
Darren
your question is little bit confusing, because you have not explained what you want to do. As i got your question, you want to fetch random id from randomids table and after performed some processing on nextid you want to insert it into resident table [newresidentid] and end of the procedure you fetch data from resident table. if i get anything wrong feel free to ask me.
your procedure solution is following.
CREATE PROCEDURE [TestId]
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NEWID NVARCHAR(30)
DECLARE #GENID BIGINT
DECLARE #BRGYCODE VARCHAR(5) = '23548'
DECLARE #COUNT INTEGER
DECLARE #ERR NVARCHAR(20) = 'NO IDS IN RANDOM ID'
SET #COUNT = (SELECT COUNT(NEXTID) FROM RandomIds WHERE [IsUsed] = 0)
SET #GENID = (SELECT TOP(1) [NEXTID] FROM RandomIds WHERE [IsUsed] = 0 ORDER BY [ID] ASC)
--SELECT #GENID AS ID
IF #COUNT = 0
BEGIN
SELECT #ERR AS ERROR
END
ELSE
BEGIN
SET #NEWID = #BRGYCODE + '-' + CAST(#GENID AS varchar(30))
UPDATE RandomIds SET [IsUsed] = 1 WHERE [NextId] = #GENID
INSERT INTO Residents ([NewResidentId] , [ResLogDate] ) VALUES (#NEWID , GETDATE())
SELECT * FROM Residents
END
END
this procedure will fetch data from your randomids table and perform some processing on nextid than after it directs insert it into resident table and if you want to insert some data through user you can use parameter after declaring procedure name
E.G
CREATE PROCEDURE [TESTID]
#PARAM1 DATATYPE,
#PARAM2 DATATYPE
AS
BEGIN
END
I'm not convinced that your requirement is a good one but here is a way to do it.
Bear in mind that concurrent sessions will not be able to read your update until it is committed so you have to kind of "lock" the update so you will get a block until you're going to commit or rollback. This is rubbish for concurrency, but that's a side effect of this requirement.
declare #cap table ( capturedValue int);
declare #GENID int;
update top (1) RandomIds set IsUsed=1
output inserted.NextID into #cap
where IsUsed=0;
set #GENID =(select max( capturedValue) from #cap )
A better way would be to use an IDENTITY or SEQUENCE to solve your problem. This would leave gaps but help concurrency.

Can I use output variables to get a value?

I have a stored procedure where I'm checking if username exists and if it does not exists insert into user table then gets userid for the same username. I was trying to use an output variable to get the userid. Am I going about this wrong?
alter Procedure Check_User_Name
(
#username varchar(25),
#password varchar(100),
#role_id integer,
#idn nvarchar output
)
As
Begin
IF NOT EXISTS(SELECT idn=#idn
FROM [user] WHERE username = #username)
BEGIN
INSERT INTO [user] (username,[password],role_id) VALUES
(#username, #password,#role_id)
--select #idn=idn from [user]
Print 'UserName inserted successfully'
End
Else IF EXISTS(SELECT * FROM [user] WHERE username = #username)
Begin
Print 'UserName already exists'
End
END
You had it close -- After replacing your column names to match with what is in my user table, this worked for me. (I think I replaced everything back).
On your Else, you're basically doing a second lookup by username - which is unnecessary in this case.
ALTER Procedure Check_User_Name
(
#username varchar(25),
#password varchar(100),
#role_id integer,
#idn nvarchar(20) output
)
As
Begin
IF NOT EXISTS(SELECT idn
FROM [user] WHERE username = #username)
BEGIN
INSERT INTO [user] (username,[password], role_id) VALUES
(#username, #password)
select #idn=idn from [user] WHERE username = #username
Print 'UserName inserted successfully'
End
Else
Begin
Print 'UserName already exists'
SELECT #idn = idn FROM [user]
WHERE username = #username
End
END
GO
Execute with:
DECLARE #idnOut nVarChar(20)
exec Check_User_Name #username = 'user2127184', #password = 'asdf', #role_id = 0, #idn = #idnOut OUTPUT
SELECT #idnOut
You can use out params, but I always avoid out params in SQL like I do in C# for the same reasons.
If you have a result set with just the UserId:
select #UserId;
then you expand it to include other things later:
select #UserId, #UserGuid;
without much trouble.
Even if you need to return a status (Login Allowed / Locked Out) and details you can just use multiple result sets:
select #Status;
select #UserId; //etc.
If you have out parameters you have to change the Signature of the procedure - which can be a problem if you are supporting multiple clients calling it.
The only change you need to make to the calling code with result sets is to keep finding the new column from the result set.

Using variables in a SQL query which change for each returned record

To begin - I am new at SQL; be gentle.
I work with a school district and have recently been given "the keys" to access the database. I am interested in getting a list of students, and then generating a list of passwords for them. I have found some code which allows me to generate random passwords that I would like to incorporate into a SQL query which is gathering information from our Student database. (Thank you if this code is yours!)
My issue is that I have not been able to use the variables to create a different password for each record. I get the same randomly generated password for each student. (On a good note; at least the password changes each time I execute the query.)
I should mention that I have two accounts set up for the database access; one to simply read the information, and another with full editing rights. (I have only used this once and closed my eyes as I pushed the big red button to update some trivial information).
Results from the first run:
Name Password
JACEK mtwsz2ybu
CARL mtwsz2ybu
LARS mtwsz2ybu
Results from the second run:
Name Password
JACEK je4tm5ptw
CARL je4tm5ptw
LARS je4tm5ptw
This is the query I am running:
USE XXTableXX
DECLARE #position int, #string char(100), #length int,
#rand int, #newstring char(15), #newchar char(15);
SET #position = 1;
SET #string = 'abcdefghijkmnopqrstuvwxyz23456789';
SET #length = 9;
SET #newstring = ''
SET #newchar = ''
WHILE #position <= #length
BEGIN
SET #rand = FLOOR(RAND()*(33-1)+1);
SET #newchar = SUBSTRING(#string,#rand,1);
SET #newstring = STUFF(#newstring,len(#newstring)+1,1,#newchar)
SET #position = #position +1;
END;
SELECT DISTINCT s.firstname, #newstring AS [Password]
FROM XXStudentTableXX s
Put all the stuff above the query in a function and call the function in your query. A side note, it will execute for each row, which means a bit of a performance hit for large sets.
Here is a way to do this.
First, you will need to make the RAND() into it's own view since you can't call it from a function
CREATE VIEW [dbo].[NewRandom]
AS
SELECT RAND() AS [RandSeed]
GO
Now you must create your function that uses the view. This function accepts an integer so you can do variable password lengths. You can hardcode it in your query or take out the parameter and hard code it in the function.
CREATE FUNCTION [dbo].[ufn_GeneratePassword] ( #PasswordLength INT )
RETURNS VARCHAR(20)
AS
BEGIN
DECLARE #position int, #string char(100), #length int,
#rand int, #newstring char(15), #newchar char(15);
SET #position = 1;
SET #string = 'abcdefghijkmnopqrstuvwxyz23456789';
SET #length = #PasswordLength;
SET #newstring = ''
SET #newchar = ''
WHILE #position <= #length
BEGIN
SET #rand = FLOOR((SELECT RandSeed FROM dbo.[NewRandom])*(33-1)+1);
SET #newchar = SUBSTRING(#string,#rand,1);
SET #newstring = STUFF(#newstring,len(#newstring)+1,1,#newchar)
SET #position = #position +1;
END
RETURN #newstring
END
Now you can call the function on every row of your table
SELECT DISTINCT s.firstname, [dbo].[ufn_GeneratePassword](9) AS [Password]
FROM XXStudentTableXX s
I think what you will need to do for this is create a table, or table variable, then instead of selecting make it insert into the table. Also Add a loop that loops 1x for each student ID. This will then insert 1 row for each student and run the randomizer 1 time.
First covert your procedure into a scalar SQL function.
CREATE VIEW dbo.RandomNumberView
AS
SELECT RandomNumber = RAND();
GO
CREATE FUNCTION dbo.GeneratePassword()
RETURNS char(15)
AS
-- Generates and Returns a random password
BEGIN
DECLARE #position int, #string char(100), #length int,
#rand int, #newstring char(15), #newchar char(15);
SET #position = 1;
SET #string = 'abcdefghijkmnopqrstuvwxyz23456789';
SET #length = 9;
SET #newstring = ''
SET #newchar = ''
WHILE #position <= #length
BEGIN
SELECT #rand = FLOOR(RandomNumber *(33-1)+1) FROM RandomNumberView;
SET #newchar = SUBSTRING(#string,#rand,1);
SET #newstring = STUFF(#newstring,len(#newstring)+1,1,#newchar)
SET #position = #position +1;
END;
RETURN #newstring;
END;
GO
And then you can easily use it whatever way you want.
SELECT DISTINCT s.firstname, dbo.GeneratePassword() AS [Password]
FROM XXStudentTableXX s
Note that each time you run this query you would get different password against the same record. I would prefer to use this function to only generate and insert password in the table and not as a direct select statement.
To get the data from a random table, SQL Server provides the NEWID () function. As its name says every execution is generated a new GUID (Global Unique Identifier), these GUIDs are unique, so the value of the order will never be the same.
Therefore you do not need to create a random function that does it for you. So you may have your answer using a simple SQL.
CREATE TABLE STUDENT (
[ID] INT IDENTITY (1, 1) NOT NULL,
[NAME] NVARCHAR (100) NULL
);
INSERT INTO STUDENT (NAME) VALUES ('John');
INSERT INTO STUDENT (NAME) VALUES ('Carl');
INSERT INTO STUDENT (NAME) VALUES ('Mary');
INSERT INTO STUDENT (NAME) VALUES ('Joan');
select
ID
,NAME
,CONCAT(
CAST((ABS(CHECKSUM(NEWID()))%10) as varchar(1))
, CHAR(ASCII('a') + (ABS(CHECKSUM(NEWID())) % 25))
, CHAR(ASCII('A') + (ABS(CHECKSUM(NEWID())) % 25))
, LEFT(LOWER(NEWID()),2)
, LEFT(NEWID(),2)
, LEFT(LOWER(NEWID()),2)
) AS PASSWORD
from STUDENT
SQL Fiddle
However, you may wish to Make your own generator taking into account a high level of complexity generated password.
https://www.simple-talk.com/blogs/2009/09/30/strong-password-generator/

Can't insert a second row into a table though it insert first row by stored procedure

It inserted a first row successfully but it's not inserting any other row, though second row has no conflict of primary key
Code in my aspx.cs file:
outputParVal = sqlCmd.Parameters[outputParName].Value;
outparameter in stored procedure is--- "Result"
CREATE PROCEDURE [dbo].[RecruiterProfileInsert]
#CompanyId int,
#CompanyName varchar(200),
#EmailId varchar(50) ,
#Password varchar(20) ,
#ContactNumber varchar(15),
#Website varchar(50),
#CompanyProfile varchar(2000),
#IsVerified bit,
#Result Tinyint OutPut
--#CreatedDate datetime ,
--UpdatedDate datetime
AS
BEGIN
-- Insert statements for procedure here
--check whether #CompanyName already exist or not if exist then return
IF EXISTS(SELECT Top 1 * FROM RecruiterProfile WHERE #CompanyId = LTRIM(RTRIM(#CompanyId)))
BEGIN
SET #Result = 0-- Already Exists
END
ELSE
BEGIN
INSERT INTO RecruiterProfile
(
CompanyId,
CompanyName,
EmailId ,
Password ,
ContactNumber,
Website ,
CompanyProfile ,
IsVerified,
CreatedDate
)
VALUES
(
#CompanyId,
#CompanyName,
#EmailId ,
#Password,
#ContactNumber,
#Website,
#CompanyProfile,
#IsVerified,
GetDate()
)
set #Result =1
return
END
END
This is the problem:
SELECT Top 1 * FROM RecruiterProfile WHERE #CompanyId = LTRIM(RTRIM(#CompanyId))
This inherently makes no sense. You're comparing the variable to itself. Take the # sign out of one of the CompanyId references. The RTrim is unnecessary in SQL Server, and the LTrim doesn't make sense either because the later insert doesn't also LTrim so something is going to go wrong eventually.
Furthermore, inside of an EXISTS clause, TOP makes no sense unless you are using ORDER BY and doing something with the final result. Just do SELECT * inside of EXISTS clauses.
One more thing: if there is high concurrency and users could possibly try to insert the same thing at the same time, your query could still fail on a duplicate key violation.

Is there a way to import a long list of new users to DNN

I have a new DNN site and a long list of users that must be added. How can I create these new users with a script.
I have seen modules for sale but if possible I would like to avoid buying a module.
For anyone still searching for an open source module to import users, there is this one http://usersimporter.codeplex.com/ that works well with the latest DNN version. It takes an Excel spreadsheet as input.
I have had good luck using this module to import users. DNNVillage Import Export User Pro It imports and exports users using an easily modified XML file. If you use excel to insert your user list into the xml file and then import it you should be good to go. The best part is that the module is free.
I'm working with DNN 4.4 and 4.9 and had the same problem. My solution to this was to develop a DNN module for this that could import from CSV or TAB separated text file. My advice would be to either buy or develop a module.
If you are intersted in writting your own I could provide you with code snippets what to do. Just let me know...
Snowcovered has a few built modules out there - (http://www.snowcovered.com/snowcovered2/Default.aspx?tabid=295&search=import+user) -
I have also written scripts to do this from one or anther of spreadsheets or some other database
A sql script to do this really just needs to add the right info
heres most a script i use to import from some access dbs - may not be great or elegant but it works!
SET NOCOUNT ON;
declare #SQLText nvarchar(max)
DECLARE #ErrMsg nvarchar(4000), #ErrSeverity int
BEGIN TRY
BEGIN TRANSACTION
-- Insert statements for procedure here
DECLARE #ApplicationName nvarchar(256)
SET #ApplicationName = 'DotNetNuke'
DECLARE #LastName nvarchar(max)
DECLARE #FirstName nvarchar(max)
DECLARE #EmployeeID nvarchar(max)
DECLARE #ContactEmail nvarchar(max)
DECLARE UserLoop CURSOR Fast_Forward
FOR SELECT [Employee] as EmployeeID, isnull([LastName],'') as employee_Lastname, isnull([FirstName],'') as emplyee_firstname, 'na#na.com' as contactemail
from openrowset('Microsoft.ACE.OLEDB.12.0', 'Excel 8.0;Database=C:\_projects\hc.xls;HDR=YES', 'SELECT * FROM [Sheet1$]')
--WHERE CustomerID in (SELECT OldID FROM dbo.RCIWebApps_LocationInfo WHERE OwnerID = #NewCustomerNumber)
Open UserLoop
FETCH NEXT FROM UserLoop INTO #EmployeeID, #LastName, #FirstName, #ContactEmail
WHILE ##FETCH_STATUS = 0
BEGIN
----
---Make unique usernames - adding one to the list until it doesnt match
DECLARE #NewUsername nvarchar(max)
SET #NewUserName = REPLACE(#Firstname + '_' + #LastName, ',','_')
DECLARE #UserNameTest int
SET #UsernameTest = 1
DECLARE #UserNameNumber int
SET #UserNameNumber = 1
DECLARE #UserNameTemp nvarchar(max)
SET #UserNameTemp = #NewUserName
WHILE #UserNameTest > 0
BEGIN
SELECT #UsernameTest = count(*) FROM rcidnn..Users WHERE Username = #UserNameTemp
IF #USernametest > 0
BEGIN
SET #UsernameTemp = #NewUserName + convert(nvarchar(max),#UserNameNumber)
SET #UserNameNumber = #UserNameNumber + 1
END
END
SET #NewUserName = #UserNameTemp
----
DECLARE #Password nvarchar(128)
--From the existing user
SET #Password = 'iIFBTBSKXithnIDFau1miTih903eL/z5qgbcyMOflIM='
DECLARE #PasswordSalt nvarchar(128)
--From the existing user
SET #PasswordSalt = '4DmxPzt6MYScaGuwNHeUDw=='
DECLARE #PasswordQuestion nvarchar(256)
SET #PasswordQuestion = ''
DECLARE #PasswordAnswer nvarchar(128)
SET #PasswordAnswer = ''
DECLARE #IsApproved bit
SET #IsApproved = 1
DECLARE #CurrentTimeUtc datetime
SET #CurrentTimeUtc = GETDATE()
DECLARE #CreateDate datetime
SET #CreateDate = #CurrentTimeUtc
DECLARE #UniqueEmail int
SET #UniqueEmail = 0
DECLARE #PasswordFormat int
SET #PasswordFormat = 2 --NOTE: Value from existing user!
DECLARE #PortalId int
SET #PortalId = 6 --The id of your portal
Declare #UserId uniqueidentifier
DECLARE #DNNUserId int
--Make the stored procedure call
EXEC rcidnn.dbo.aspnet_Membership_CreateUser #ApplicationName, #NewUsername, #Password,
#PasswordSalt, #contactemail, #passwordquestion, #PasswordAnswer,
#IsApproved, #CurrentTimeUtc, #CreateDate, #UniqueEmail,
#PasswordFormat, #UserId
--Insert the record into the DotNetNuke users table
print #NewUsername
INSERT INTO rcidnn..users (Username, FirstName, LastName, IsSuperUser, Email,
DisplayName, UpdatePassword)
VALUES(#NewUsername, #FirstName, #LastName, 0, #ContactEmail, #Firstname + ' ' + #LastName, 0)
--Get the new userid, from the DNN users table
SELECT #dnnuserid = userid
FROM rcidnn..Users
WHERE username = #NewUsername
--Now, insert the record into the user portals table
INSERT INTO rcidnn..UserPortals (userId, PortalId, CreatedDate)
VALUES(#dnnuserid, #PortalId, GETDATE())
--Now Give the user permissions to the RECISTERED Users group
INSERT INTO rcidnn..UserRoles (userId, roleId)
SELECT #dnnuserid,
roleId
FROM rcidnn..Roles
WHERE (RoleName = 'Registered Users' or RoleName = 'Subscribers' or RoleName = 'G - Location View')
and portalid = #PortalId
--ADD info into profile??
INSERT rcidnn.dbo.UserProfile
VALUES ( #DNNUserID, 167, #NewCustomerNumber, null, 2, getdate())
----
FETCH NEXT FROM UserLoop INTO #EmployeeID, #LastName, #FirstName, #ContactEmail
END
CLOSE Userloop
DEALLOCATE userloop
COMMIT
Print 'Transfered'
END TRY
BEGIN CATCH
-- Whoops, there was an error
IF ##TRANCOUNT > 0
ROLLBACK
-- Raise an error with the details of the exception
SELECT #ErrMsg = ERROR_MESSAGE(),
#ErrSeverity = ERROR_SEVERITY()
RAISERROR(#ErrMsg, #ErrSeverity, 1)
END CATCH
The best product I have used is 'Bulk User Manager'. Not free, but WELL worth the $30. It will save hours of work, and Time is Money!
Here is the link to the product on the DNN Store:
http://store.dnnsoftware.com/home/product-details/bulk-user-manager-v33

Resources