Exit from stored procedure in sybase - sap-ase

I am getting some parameters in my stored procedure. Before operating on these parameters, I want to validate them and if the parameters are not as per the requirement then I want to exit from the stored procedure with an error message.
sample code:
create proc abcd
(
zip varchar(20),
name varchar(20),
network varchar(1)
)
-- validation section
IF (len(zip)<>5 OR LEN(zip)<>9)
begin
print "The zip must be of 5 or 9 characters"
<---- how to exit from here--->
end
IF (len(name)<2)
begin
print "The name must be of at least 2 characters"
<---- how to exit from here--->
end
---- main code
How can I exit the procedure once I get the error as mentioned above?

You can use return command as below
-- validation section
IF (len(zip)<>5 OR LEN(zip)<>9)
begin
print "The zip must be of 5 or 9 characters"
return 1
end
IF (len(name)<2)
begin
print "The name must be of at least 2 characters"
return 2
end
return 0 -- on the end of procedure
to catch the result you can use this code:
declare #ProcResult int
execute #ProcResult = abcd #Zip = ..., #name...
select #ProcResult

Let me suggest a few changes:
create procedure abcd
#zip varchar(20),
#name varchar(20),
#network varchar(1)
AS
-- validation section
IF (len(#zip)<>5 AND LEN(#zip)<>9)
begin
-- print "The zip must be of 5 or 9 characters"
raiserror 20000 "The zip must be of 5 or 9 characters"
return 1
end
IF (len(#name)<2)
begin
-- print "The name must be at least 2 characters"
raiserror 20001 "The name must be at least 2 characters"
return 2
end
There are numerous options with raiserror but this should point you in the right direction.
Edit: added return statements

Related

Analyze log data with occassional multiline logs

I need to scan a log file for users that ran certain SQL statements (DROP,CREATE,etc.), and return an array with the users and which SQL ddl's they tried(drop,create,etc.).
I have log files where each line normally looks like this:
'2019-01-14T-19:23:50Z UTC' [ db=dev user=joeschmoe pid=123 userid=1 xid=1234]' Log: Select *
however, sometimes the select statement will span multiple lines like this:
'2019-01-14T19:23:50Z UTC [ db=dev user=rb pid=16 userid=1 xid=8 ]' LOG: SELECT SUM (num_queries) num_all_queries
,SUM (CASE WHEN lalala is not null THEN num_queries ELSE 0 END) num_b
,SUM (CASE WHEN lalala is null THEN num_queries ELSE 0 END) num_non_b
,SUM (total_queue_time_min) total_queue_time_min
,SUM (CASE WHEN lalala is not null THEN total_queue_time_min ELSE 0 END) b_total_queue_time_min
,SUM (CASE WHEN lalala is null THEN total_queue_time_min ELSE 0 END) non_b_total_queue_time_min
,SUM (CASE WHEN lalala is not null THEN duration_s ELSE 0 END)/60.0 total_burst_usage_min
,SUM (CASE WHEN lalala is not null THEN 1 ELSE 0 END) num_lalalas
,MIN(firsttime) mintime
,MAX(lasttime) maxtime
,DATEDIFF (seconds, mintime, maxtime) workload_duration_s
,wration_s/60.0 workload_duration_min
LEFT JOIN (SELECT b FROM STfdaf LIMIT 1) sq ON sq.but_reon < 100
;
I am combing these logs for certain keywords in the SQL statements. I can write the regex to handle that but I need help getting this log in a format I can work with. I was originally using a for loop and a regex
for line in input:
user_match = re.search("DROP", line, re.IGNORECASE)
This wouldn't be accurate because when a sql statement spans multiple lines I wouldn't be able to tie the "DROP" back to the "USER" if the DROP occurred many lines after the initial line.
I'm not sure how to go about doing this. Whether its turning this text file into a list in python and programmatically combining multiple lines into one or whatever other options there may be.
I solved this issue by storing the user value in a variable that only updates if a match is found using RegEx. So if a keyword is found, the user value last stored in the variable would be returned along with the keyword.
for line in input:
error = []
user_match = re.search("USER=b[0-9]{6}", line, re.IGNORECASE)
serviceuser = re.search("USER=[a-z0-9]*", line, re.IGNORECASE)
if serviceuser:
user = (serviceuser.group().split("=")[1])
elif user_match:
user = (user_match.group().split("=")[1])
ddl = re.search(
"LINK|.DELETE.|INSERT|TRIGGER|TRUNCATE|UPDATE|WRITE", line, re.IGNORECASE)
if ddl:
error.append(user)
error.append(ddl.group())

Opening files specifying status and position

According to this source, I would interpret that specifying status="old" should append by default:
OLD, if the file is to be opened but not replaced
However, that is not what is happening in my codes. Here is an example:
program openstat_test
implicit none
integer :: mystat
mystat=0
print*,"Im trying to open a new file..."
open( unit=100, file="output.txt", status="new", iostat=mystat )
if ( mystat == 17 ) then
print*,"File already exists; overwriting!"
open( unit=100, file="output.txt", status="replace", iostat=mystat )
end if
if ( mystat /= 0 ) then
print*, "Error prevents test..."; stop
end if
write( unit=100, fmt=* ) "Line number 1"
close( unit=100)
print*,"Im trying to open an old file..."
open( unit=100, file="output.txt", status="old", iostat=mystat )
if ( mystat /= 0 ) then
print*, "Error prevents test..."; stop
end if
write( unit=100, fmt=* ) "Line number 2"
close( unit=100)
print*,"Im trying to open an old file AND FORCING APPEND..."
open( unit=100, file="output.txt", status="old", position="append", iostat=mystat )
if ( mystat /= 0 ) then
print*, "Error prevents test..."; stop
end if
write( unit=100, fmt=* ) "Line number 3"
close( unit=100)
end program openstat_test
("output.txt" only has "Line number 2" and "Line number 3"; the second open that uses status="old" is overwriting)
Am I'm missing something? Do you always need to specify position="append" even with status="old"? If so, why does the reference specify that "old" means opening but not replacing if the default writing command will overwrite the file?
Analogously, would it be safe to use position="append" without status (or with "unknown") to either create a new file or if the file exists append to it? I tried it and it works, but here says that the safe way to do it is case selecting without really explaining why or what could go wrong.
At a filesystem level there may well be differences between deleting a file then creating one with the same name and overwriting the contents of a file. This could relate to attributes or permissions and so on.
status='old' means that the named file exists at the time of connection. status='replace' for a file which exists first deletes the file and then creates a new one with the same name.
As you can see, then, it is reasonable for status='old' to lead to overwriting. The reference you quote doesn't say exactly what the Fortran standard says.
Without giving position=... the default is 'asis'. In the case where a file isn't currently connected the file position is left unspecified. If you wish to append you should explicitly give position='append'.
With status='unknown' (the default) the status is processor dependent. It isn't possible to definitively say what that means.

rearanging data from duplicates in excel

I have an excel sheet with a list of mothers and students,
Every record shows just one student, but some of the moms have more than one student - meaning they have multiple records.
How do i move the extra students for every mom to another column on the mom's row ?
example:
to this:
Here is a short ruby script that does that (thanks to Yanik Rabe)
(The pluralize method in the beginning is not really necessary, just makes prettier error messages...)
#!/usr/bin/env ruby
# The CSV file to read from
INPUT_FILE = 'sample.csv'
# The CSV file to write to
# This can be the same as INPUT_FILE
# Existing files will be overwritten
OUTPT_FILE = 'sample.out.csv'
# The total number of cells in each row
CELL_COUNT = 10
# The number of cells for each student
# This defines how many columns contain
# student data and will therefore be
# moved to the matching row.
STDT_CELLS = 4
# ----- End of configuration -----
require 'csv'
lines = CSV.read INPUT_FILE
class String
def pluralize(n, plural = nil)
noun = \
if n == 1
dup
elsif plural
plural
else
"#{self}s"
end
"#{n} #{noun}"
end
end
class Array
def real_length
last_index = 0
(0..length).each do |i|
last_index = i if self[i] and not self[i].to_s.empty?
end
last_index + 1
end
end
lines.each_with_index do |line, i|
next unless line
if line.length < CELL_COUNT
missing = CELL_COUNT - line.length
noun = 'missing cell'.pluralize missing
STDERR.puts "Warning: #{noun} on line #{i+1} will be filled with an empty string in the output"
while line.length < CELL_COUNT
line << ''
end
end
# Check for other entries with the same parent email
lines.each_with_index do |dline, di|
next unless dline
next if i == di
next if dline.empty?
if line.first == dline.first
((CELL_COUNT - STDT_CELLS)..(CELL_COUNT - 1)).each do |i|
line[line.real_length] = dline[i]
end
lines[di] = nil
end
end
end
CSV.open OUTPT_FILE, 'wb' do |csv|
lines.each do |line|
csv << line if line
end
end
puts "Read #{INPUT_FILE} (#{lines.length} lines), wrote #{OUTPT_FILE} (#{lines.compact.length} lines). Have a nice day!"

inno setup- Passing File path as a command line parameter

I am passing a set of parameters from main setup through the command line which also includes file paths and reading the values in Subsetup. The command line parameters output looks like below
/dir="D:\XXX.Web" /dbname="XXX" /dbinstancename="XXX" /dbsapwd="123!"#$%" /dataFileDirectory="D:\MSSQL10_50.XXX\MSSQL\DATA" /logFileDirectory="D:\MSSQL10_50.XXX\MSSQL\Log" /backupDirectory="E:\MSSQL10_50.XXX\MSSQL\Backup" /sqlCmdLocation="C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" /webappname="yyyy" /Nameservice="VVVV" /UserUsername="user"
I am getting the parameter values in the Subsetup using a custom GetParameter function and storing in the String like mentioned below...
// This is how I get the values and store in String
DBName := GetParameter('/dbname=', DBName);
DataFileDirectory := GetParameter('/dataFileDirectory=', DataFileDirectory);
// function to get the parameters from the commandline parameters
function GetParameter(ParamName, Default: String): String;
var
P, I: Integer;
begin
Result := Default;
if Length(ParamName) < 1 then Exit;
ParamName := Lowercase(ParamName);
for I := 2 to ParamCount() do begin
P := pos(ParamName, Lowercase(ParamStr(I)));
if P > 0 then begin
P := P + Length(ParamName);
Result := Copy(ParamStr(I), P, Length(ParamStr(I))+1-P);
Result := Trim(RemoveQuotes(Trim(Result)));
Exit;
end;
end;
end;
When I print all the values in the log file, I am getting the output like mentioned below.
DBName = XXX
DBSaPwd = ********
DBInstanceName = XXX
DataFileDirectory = D:\MSSQL10_50.XXX\MSSQL\DATA /logFileDirectory=D:\MSSQL10_50.XXX\MSSQL\Log /backupDirectory=E:\MSSQL10_50.XXX\MSSQL\Backup /sqlCmdLocation=C:\Program
LogFileDirectory = D:\MSSQL10_50.XXX\MSSQL\Log /backupDirectory=E:\MSSQL10_50.XXX\MSSQL\Backup /sqlCmdLocation=C:\Program
BackupDirectory = E:\MSSQL10_50.XXX\MSSQL\Backup /sqlCmdLocation=C:\Program
SqlCmdLocation = C:\Program
WebAppName = yyyy /Nameservice=VVVV /UserUsername=user /UserPassword=user /MSSQLServerSelection= /silent /restart=false
The file path value of DataFileDirectory for example is taking the next parameter values and so on for the subsequent values which is throwing "File name, directory name or volume label syntax is incorrect" error at the end of the setup execution.
I believe an escape sequence must be used to solve this problem. Please provide your suggestions to solve this error and to implement it correctly.
Thanks in advance
DeeJay

Split a string on sqlite

i don't know sqlite but I have to implement a database already done. I'm programming with Corona SDK. The problem: i have a column called "answers" in this format: House,40|Bed,20|Mirror,10 ecc.
I want to split the string and remove "," "|" like this:
VARIABLE A=House
VARIABLE A1=40
VARIABLE B=Bed
VARIABLE B1=20
VARIABLE C=Mirror
VARIABLE C1=10
I'm sorry for my english. Thanks to everybody.
Try this:
If you want to simply remove the characters, then you can use the following:
Update 3 :
local myString = "House;home;flat,40|Bed;bunk,20|Mirror,10"
local myTable = {}
local tempTable = {}
local count_1 = 0
for word in string.gmatch(myString, "([^,|]+)") do
myTable[#myTable+1]=word
count_1=count_1+1
tempTable[count_1] = {} -- Multi Dimensional Array
local count_2 = 0
for word_ in string.gmatch(myTable[#myTable], "([^,|,;]+)") do
count_2=count_2+1
local str_ = word_
tempTable[count_1][count_2] = str_
--print(count_1.."|"..count_2.."|"..str_)
end
end
print("------------------------")
local myTable = {} -- Resetting my table, just for using it again :)
for i=1,count_1 do
for j=1,#tempTable[i] do
print("tempTable["..i.."]["..j.."] = "..tempTable[i][j])
if(j==1)then myTable[i] = tempTable[i][j] end
end
end
print("------------------------")
for i=1,#myTable do
print("myTable["..i.."] = "..myTable[i])
end
--[[ So now you will have a multidimensional array tempTable with
elements as:
tempTable = {{House,home,flat},
{40},
{Bed,bunk},
{20},
{Mirror},
{10}}
So you can simply take any random/desired value from each.
I am taking any of the 3 from the string "House,home,flat" and
assigning it to var1 below:
--]]
var1 = tempTable[1][math.random(3)]
print("var1 ="..var1)
-- So, as per your need, you can check var1 as:
for i=1,#tempTable[1] do -- #tempTable[1] means the count of array 'tempTable[1]'
if(var1==tempTable[1][i])then
print("Ok")
break;
end
end
----------------------------------------------------------------
-- Here you can print myTable(if needed) --
----------------------------------------------------------------
for i=1,#myTable do
print("myTable["..i.."]="..myTable[i])
end
--[[ The output is as follows:
myTable[1]=House
myTable[2]=40
myTable[3]=Bed
myTable[4]=20
myTable[5]=Mirror
myTable[6]=10
Is it is what you are looking for..?
]]--
----------------------------------------------------------------
Keep coding............. :)

Resources