Below is a quote bot script that I created a while ago.
It stores the quotes in a ini file, and stores a lot of additional information.
It wouldn't work for your own nick, but if you load it on a bot, it should work.
The help is a bit limited, but with it, I guess you could make your own version of it, and improve it however you like.

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Add Quote
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on *:TEXT:!aquote*:#:{
  if (!$2) { notice $nick Invalid syntax, use: 7!aquote <7Quote> (7!help for all bot commands, 7!quotehelp for all quote commands) | halt }
  else {
    %quote_counter = $calc(%quote_counter + 1)
    set %inifile quotes.ini
    writeini %inifile %quote_counter ID %quote_counter
    writeini %inifile %quote_counter Quote $2-
    writeini %inifile %quote_counter Date $date
    writeini %inifile %quote_counter Time $time
    writeini %inifile %quote_counter Nick $nick
    writeini %inifile %quote_counter Address $address($nick,1)
    writeini %inifile %quote_counter Channel $chan
    writeini %inifile %quote_counter Visible yes
    writeini %inifile %quote_counter RemovedBy N/A
    writeini %inifile %quote_counter RemovedOnDate N/A
    writeini %inifile %quote_counter RemovedonTime N/A
    writeini %inifile %quote_counter RemovedOnChannel N/A
    msg $chan 3Added Quote ( $+ %quote_counter $+ ): 5 $+ $2- $+ 
    unset %inifile
  }
}
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Read Quote
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on *:TEXT:!rquote*:#:{
  if (!$2) {
    set %qID $rand(1,%quote_counter)
    if ($readini(quotes.ini, %qID, Visible) == Yes) {
      set %qMSG $readini(quotes.ini, %qID, quote)
      set %qReply 3Random Quote ( $+ %qID of %quote_counter $+ ): 5 $+ %qMSG $+ 
      msg $chan %qReply
    unset %qID | unset %qMSG | unset %qReply | halt }
    else {
      set %qID $rand(1,%quote_counter)
      while ($readini(quotes.ini, %qID, Visible) == No) { set %qID $rand(1,%quote_counter) }
      set %qMSG $readini(quotes.ini, %qID, quote)
      set %qReply 3Random Quote ( $+ %qID of %quote_counter $+ ): 5 $+ %qMSG $+ 
      msg $chan %qReply
    unset %qID | unset %qMSG | unset %qReply | halt }
  }
  elseif ($2 isnum) {
    set %qID $2
    set %qMSG $readini(quotes.ini, %qID, quote)
    if (!%qMSG) {
      set %qID $rand(1,%quote_counter)
      if ($readini(quotes.ini, %qID, Visible) == Yes) {
        set %qMSG $readini(quotes.ini, %qID, quote)
        set %qReply 3Random Quote ( $+ %qID of %quote_counter $+ ): 5 $+ %qMSG $+ 
        msg $chan %qReply
      unset %qID | unset %qMSG | unset %qReply | halt }
      else {
        set %qID $rand(1,%quote_counter)
        while ($readini(quotes.ini, %qID, Visible) == No) { set %qID $rand(1,%quote_counter) }
        set %qMSG $readini(quotes.ini, %qID, quote)
        set %qReply 3Random Quote ( $+ %qID of %quote_counter $+ ): 5 $+ %qMSG $+ 
        msg $chan %qReply
      unset %qID | unset %qMSG | unset %qReply | halt }
    }
    else {
      if ($readini(quotes.ini, %qID, Visible) == Yes) {
        set %qReply 3Quote %qID $+  5 $+ %qMSG $+ 
        msg $chan %qReply
      unset %qID | unset %qMSG | unset %qReply | halt }
      else {
        set %qReply 3Quote ( $+ %qID of %quote_counter $+ ): 5This quote has been removed from the database.
        msg $chan %Qreply
      unset %qID | unset %qMSG | unset %qReply | halt }
    }
  }
}
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Quote Details
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on *:TEXT:!qinfo*:#:{
  if (!$2) { notice $nick Invalid syntax, use: 7!qinfo <7Quote ID> | halt }
  if ($2 isnum) {
    set %qID $2
    set %qMSG $readini(quotes.ini, %qID, quote)
    if (!%qMSG) { notice $nick Invalid Quote ID ( $+ $2 $+ ) specified. | unset %qID | unset %qMSG | halt }
    elseif ($readini(quotes.ini, %qID, Visible) == no) {
      notice $nick 3Quote ( $+ %qID of %quote_counter $+ ): 5This quote has been removed from the database.
    notice $nick 3Removed by: 5 $+ $readini(quotes.ini, %qID, RemovedBy) $+  $+ 3, on 05 $+ $readini(quotes.ini, %qID, RemovedOnDate) $+  3( $+ 05 $+ $readini(quotes.ini, %qID, RemovedOnTime) $+  $+ 3) | unset %qID | unset %qMSG | halt }
    else {
      notice $nick 3Quote ( $+ %qID of %quote_counter $+ ): 5 $+ %qMSG $+ 
    notice $nick 3Added by: 5 $+ $readini(quotes.ini, %qID, Nick) $+  $+ 3, on 05 $+ $readini(quotes.ini, %qID, Date) $+  3( $+ 05 $+ $readini(quotes.ini, %qID, Time) $+  $+ 3) | unset %qID | unset %qMSG | halt }
  }
  else { notice $nick Invalid Quote ID ( $+ $2 $+ ) specified. | unset %qID | unset %qMSG | halt }
}
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Remove Quote
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on *:TEXT:!dquote*:#:{
  if (!$2) { notice $nick Invalid syntax, use: 7!dquote <7Quote ID> | halt }
  if ($2 isnum) {
    set %qID $2
    set %qMSG $readini(quotes.ini, %qID, quote)
    if (!%qMSG) { notice $nick Invalid Quote ID ( $+ $2 $+ ) specified. | unset %qID | unset %qMSG | halt }
    elseif ($readini(quotes.ini, %qID, Visible) == no) { notice $nick This Quote ID ( $+ $2 $+ ) has already been removed. | unset %qID | unset %qMSG | halt }
    else ($readini(quotes.ini, %qID, Visible) == yes) {
      set %inifile quotes.ini
      writeini %inifile %qID Visible no
      writeini %inifile %qID RemovedBy $nick
      writeini %inifile %qID RemovedOnDate $date
      writeini %inifile %qID RemovedOnTime $time
      writeini %inifile %qID RemovedOnChannel $chan
      msg $chan 3Removed Quote ( $+ %qID $+ )
    unset %inifile | unset %qID | unset %qMSG | halt }
  }
  else { notice $nick Invalid Quote ID ( $+ $2 $+ ) specified. | unset %qID | unset %qMSG | halt }
}
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Find Quote
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on *:TEXT:!fquote*:#:{
  if (!$2) { notice $nick Invalid syntax, use: 7!fquote <7match text here> | halt }
  else {
    set %matchtext * $+ $2- $+ *
    set %matchcounter 0
    var %loop = 1 | while (%loop <= %quote_counter) {
      set %quotestring $readini(quotes.ini, %loop, quote)
      if (%matchtext iswm %quotestring) { 
        if ($readini(quotes.ini, %loop, Visible) == yes) { var %matchedID %matchedID %loop $+ $Chr(44)
        set %matchcounter $calc(%matchcounter + 1) }
      unset %quotestring }
    inc %loop }
    if (%matchedID == $null) { msg $chan $nick $+ , I'm sorry, but your search didn't return any results. | unset %matchtext | unset %matchcounter | unset %quotestring | halt }
    else { msg $chan $nick $+ , I found $iif(%matchcounter == 1, 1 match, %matchcounter matches) to your query. The following Quote ID's contain a match with your query: %matchedID type: 7!rquote <7ID> to show the quote. | unset %matchtext | unset %matchcounter | unset %quotestring | halt }
  }
}
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


And yeah, I bet the code could be a lot shorter.
But this way, at least I understand what happens when.

Good luck.